/** Draws a kind of compass, showing the world axis */
 private void drawMouseWorldAxis() {
   Vector3 v = cursorWorldPosition;
   if (!Float.isNaN(v.x + v.y + v.z)) { // No vector component is NaN
     shapeRenderer.begin();
     shapeRenderer.line(v.x, v.y, v.z, v.x + 1, v.y, v.z, Color.RED, Color.RED);
     shapeRenderer.line(v.x, v.y, v.z, v.x, v.y + 1, v.z, Color.GREEN, Color.GREEN);
     shapeRenderer.line(v.x, v.y, v.z, v.x, v.y, v.z + 1, Color.BLUE, Color.BLUE);
     shapeRenderer.end();
   }
 }
  public GameRenderer(Viewport viewport, Camera camera, GameEngine engine) {
    this.viewport = viewport;
    this.camera = camera;
    this.engine = engine;

    shapeRenderer = new MyShapeRenderer();
    shapeRenderer.setAutoShapeType(true);

    spriteBatch = new SpriteBatch();
    font = new BitmapFont();
    font.setColor(Color.WHITE);
    font.setUseIntegerPositions(false);
    font.getData().setScale(0.01f);
    shadowBatch = new ModelBatch(new DepthShaderProvider());

    ShaderProgram.pedantic = false;
    final String vertUber = Gdx.files.internal("shaders/uber.vert").readString();
    final String fragUber = Gdx.files.internal("shaders/uber.frag").readString();
    modelBatch =
        new ModelBatch(
            new DefaultShaderProvider(vertUber, fragUber) {
              @Override
              protected Shader createShader(final Renderable renderable) {
                return new UberShader(renderable, config);
              }
            });
  }
 @Override
 public void dispose() {
   modelBatch.dispose();
   shadowBatch.dispose();
   shapeRenderer.dispose();
   spriteBatch.dispose();
   font.dispose();
   shadowLight.dispose();
 }
 public void update(float deltaTime) {
   camera.update();
   if (DebugViewSettings.drawModels) {
     drawShadowBatch();
     viewport.apply();
     modelBatch.begin(camera);
     modelBatch.render(engine.getModelCache(), environment);
     for (GameModel mdl : engine.getDynamicModels()) {
       if (isVisible(camera, mdl)) {
         modelBatch.render(mdl.modelInstance, environment);
       }
     }
     if (markerBillboard != null && isVisible(camera, markerBillboard)) {
       modelBatch.render(markerBillboard.modelInstance, environment);
     }
     modelBatch.end();
   }
   if (DebugViewSettings.drawArmature) {
     shapeRenderer.setProjectionMatrix(viewport.getCamera().combined);
     armatureDebugDrawer.drawArmature(shapeRenderer, selectedCharacter, "armature");
   }
   if (DebugViewSettings.drawSteering) {
     drawSteering();
   }
   if (DebugViewSettings.drawNavmesh) {
     shapeRenderer.setProjectionMatrix(viewport.getCamera().combined);
     navMeshDebugDrawer.drawNavMesh(
         shapeRenderer,
         spriteBatch,
         engine.getScene().navMesh,
         selectedCharacter,
         visibleLayers,
         viewport.getCamera(),
         font);
   }
   if (DebugViewSettings.drawMouseNavMeshPos) {
     shapeRenderer.setProjectionMatrix(viewport.getCamera().combined);
     drawMouseWorldAxis();
   }
 }