public void showCar() {
    for (int i = 0; i < 4; i++) {
      cars[i] = factory.getCar(car_names[i], assetManager);
      car_con[i] = cars[i].getControl(VehicleControl.class);
    }
    Camera camera = cam.clone();

    camera.setViewPort(.25f, .9f, .1f, .75f);
    carView = this.app.getRenderManager().createPostView("carview", camera);

    space.add(car_con[index]);
    dl = new DirectionalLight();
    localRootNode.addLight(dl);
    ai = new AmbientLight();
    localRootNode.addLight(ai);
    car_con[index].setPhysicsLocation(new Vector3f(0, 1, 0));
    localRootNode.attachChild(cars[index]);
    floor = assetManager.loadModel("Models/garage/garage.mesh.j3o");
    control = new RigidBodyControl(0);
    floor.addControl(control);
    control.setPhysicsLocation(Vector3f.ZERO);
    space.add(control);
    localRootNode.attachChild(floor);

    camera.setLocation(car_con[index].getPhysicsLocation().add(new Vector3f(3, 1f, 0)));
    camera.lookAt(car_con[index].getPhysicsLocation().add(new Vector3f(0, -1, 0)), Vector3f.UNIT_Y);
    dl.setDirection(camera.getDirection());

    carView.attachScene(localRootNode);
  }
  @Override
  public void cleanup() {
    localRootNode.removeLight(ai);
    localRootNode.removeLight(dl);

    this.app.getTimer().reset();
    rootNode.detachChild(localRootNode);
    viewPort.removeProcessor(niftyDisplay);
    audio.stop();
    nifty.exit();
    cam.setRotation(Quaternion.IDENTITY);
    cam.setLocation(Vector3f.ZERO);
    cam.setViewPort(0, 1, 0, 1);
    super.cleanup();
  }
  public void postQueue(RenderQueue rq) {
    GeometryList occluders = rq.getShadowQueueContent(ShadowMode.Cast);
    if (occluders.size() == 0) {
      noOccluders = true;
      return;
    } else {
      noOccluders = false;
    }

    GeometryList receivers = rq.getShadowQueueContent(ShadowMode.Receive);

    // update frustum points based on current camera
    Camera viewCam = viewPort.getCamera();
    ShadowUtil.updateFrustumPoints(
        viewCam, viewCam.getFrustumNear(), viewCam.getFrustumFar(), 1.0f, points);

    Vector3f frustaCenter = new Vector3f();
    for (Vector3f point : points) {
      frustaCenter.addLocal(point);
    }
    frustaCenter.multLocal(1f / 8f);

    // update light direction
    shadowCam.setProjectionMatrix(null);
    shadowCam.setParallelProjection(true);
    //        shadowCam.setFrustumPerspective(45, 1, 1, 20);

    shadowCam.lookAtDirection(direction, Vector3f.UNIT_Y);
    shadowCam.update();
    shadowCam.setLocation(frustaCenter);
    shadowCam.update();
    shadowCam.updateViewProjection();

    // render shadow casters to shadow map
    ShadowUtil.updateShadowCamera(occluders, receivers, shadowCam, points);

    Renderer r = renderManager.getRenderer();
    renderManager.setCamera(shadowCam, false);
    renderManager.setForcedMaterial(preshadowMat);

    r.setFrameBuffer(shadowFB);
    r.clearBuffers(false, true, false);
    viewPort.getQueue().renderShadowQueue(ShadowMode.Cast, renderManager, shadowCam, true);
    r.setFrameBuffer(viewPort.getOutputFrameBuffer());

    renderManager.setForcedMaterial(null);
    renderManager.setCamera(viewCam, false);
  }
  public void setupOffscreenView() {
    offCamera = new Camera(width, height);

    // create a pre-view. a view that is rendered before the main view
    offView = renderManager.createPreView("Offscreen View", offCamera);
    offView.setBackgroundColor(ColorRGBA.DarkGray);
    offView.setClearFlags(true, true, true);

    // this will let us know when the scene has been rendered to the
    // frame buffer
    offView.addProcessor(this);

    // create offscreen framebuffer
    offBuffer = new FrameBuffer(width, height, 1);

    // setup framebuffer's cam
    offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
    offCamera.setLocation(new Vector3f(0f, 0f, -5f));
    offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);

    // setup framebuffer's texture
    //        offTex = new Texture2D(width, height, Format.RGBA8);

    // setup framebuffer to use renderbuffer
    // this is faster for gpu -> cpu copies
    offBuffer.setDepthBuffer(Format.Depth);
    offBuffer.setColorBuffer(Format.RGBA8);
    //        offBuffer.setColorTexture(offTex);

    // set viewport to render to offscreen framebuffer
    offView.setOutputFrameBuffer(offBuffer);

    // setup framebuffer's scene
    Box boxMesh = new Box(Vector3f.ZERO, 1, 1, 1);
    Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m");
    offBox = new Geometry("box", boxMesh);
    offBox.setMaterial(material);

    // attach the scene to the viewport to be rendered
    offView.attachScene(offBox);
  }
  public void postQueue(RenderQueue rq) {
    Camera sceneCam = rm.getCurrentCamera();

    // update refraction cam
    refractionCam.setLocation(sceneCam.getLocation());
    refractionCam.setRotation(sceneCam.getRotation());
    refractionCam.setFrustum(
        sceneCam.getFrustumNear(),
        sceneCam.getFrustumFar(),
        sceneCam.getFrustumLeft(),
        sceneCam.getFrustumRight(),
        sceneCam.getFrustumTop(),
        sceneCam.getFrustumBottom());
    refractionCam.setParallelProjection(sceneCam.isParallelProjection());

    // update reflection cam
    WaterUtils.updateReflectionCam(reflectionCam, plane, sceneCam);

    // Rendering reflection and refraction
    rm.renderViewPort(reflectionView, savedTpf);
    rm.renderViewPort(refractionView, savedTpf);
    rm.getRenderer().setFrameBuffer(vp.getOutputFrameBuffer());
    rm.setCamera(sceneCam, false);
  }