Package eas.plugins.standard.visualization.visualization3D

Source Code of eas.plugins.standard.visualization.visualization3D.VideoPlugin3D

/*
* File name:        VideoPlugin3D.java (package eas.simulation.users.students.fabianRigoll.sim3D.physicalSimulation.videoPlugin3D)
* Author(s):        Fabian
* Java version:     6.0
* Generation date:  15.04.2011 (09:39:25)
*
* This class contains large parts of the JBullet Framework bei Martin Dvorak.
* Therefore the following license must be included:
*
*  * Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz>
*
* Bullet Continuous Collision Detection and Physics Library
* Copyright (c) 2003-2008 Erwin Coumans  http://www.bulletphysics.com/
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
*    claim that you wrote the original software. If you use this software
*    in a product, an acknowledgment in the product documentation would be
*    appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
*
*
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
*   author or licensor (but not in any way that suggests that they endorse
*   you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
*   distribute the resulting work only under the same or a similar license to
*   this one.
*
* + Detailed license conditions (Germany):
*   http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
*   http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/

package eas.plugins.standard.visualization.visualization3D;

import static com.bulletphysics.demos.opengl.IGL.GL_AMBIENT;
import static com.bulletphysics.demos.opengl.IGL.GL_COLOR_BUFFER_BIT;
import static com.bulletphysics.demos.opengl.IGL.GL_DEPTH_BUFFER_BIT;
import static com.bulletphysics.demos.opengl.IGL.GL_DEPTH_TEST;
import static com.bulletphysics.demos.opengl.IGL.GL_DIFFUSE;
import static com.bulletphysics.demos.opengl.IGL.GL_LESS;
import static com.bulletphysics.demos.opengl.IGL.GL_LIGHT0;
import static com.bulletphysics.demos.opengl.IGL.GL_LIGHT1;
import static com.bulletphysics.demos.opengl.IGL.GL_LIGHTING;
import static com.bulletphysics.demos.opengl.IGL.GL_MODELVIEW;
import static com.bulletphysics.demos.opengl.IGL.GL_POSITION;
import static com.bulletphysics.demos.opengl.IGL.GL_PROJECTION;
import static com.bulletphysics.demos.opengl.IGL.GL_SMOOTH;
import static com.bulletphysics.demos.opengl.IGL.GL_SPECULAR;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import javax.imageio.ImageIO;
import javax.vecmath.Matrix3f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

import com.bulletphysics.BulletGlobals;
import com.bulletphysics.BulletStats;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.demos.opengl.GLShapeDrawer;
import com.bulletphysics.demos.opengl.LwjglGL;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.linearmath.Clock;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.QuaternionUtil;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.linearmath.VectorUtil;

import eas.plugins.AbstractDefaultPlugin;
import eas.simulation.Wink;
import eas.simulation.event.EASEvent;
import eas.simulation.spatial.sim3D.physicalSimulation.standardAgents.AbstractAgent3D;
import eas.simulation.spatial.sim3D.physicalSimulation.standardEnvironments.AbstractEnvironment3D;
import eas.startSetup.ParCollection;
import eas.startSetup.SingleParameter;
import eas.startSetup.parameterDatatypes.Datatypes;

/**
*
*  * Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz>
*
* Bullet Continuous Collision Detection and Physics Library
* Copyright (c) 2003-2008 Erwin Coumans  http://www.bulletphysics.com/
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
*    claim that you wrote the original software. If you use this software
*    in a product, an acknowledgment in the product documentation would be
*    appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* @author Fabian (adapted work from Martin Dvorak's JBullet)
*
*/
public class VideoPlugin3D extends
    AbstractDefaultPlugin<AbstractEnvironment3D<AbstractAgent3D<?>>> {
 
  /**
     *
     */
    private static final long serialVersionUID = -472396947478196475L;

    private static String pfad = "VideoPlugin3DFolder";
 
  /**
   * Amount by which the camera is shifted each time.
   */
  private static final float STEPSIZE = 10;
  /**
   * Internal clock.
   */
  private Clock clock = new Clock();
  /**
   * The physics world to be drawn.
   */
  private static DynamicsWorld dynamicsWorld;
  /**
   * The camera's distance from the point it is supposed to look at.
   */
  private static float cameraDistance = 0;
  //private final static float STANDARD_CAMERA_DISTANCE = 50;
  private static float STANDARD_CAMERA_DISTANCE;
  private final static float STANDARD_CAMERA_ELE = 20f;
  private final static float STANDARD_CAMERA_AZI = 0;
  private final static Vector3f cameraUp = new Vector3f(0f, 1f, 0f);

  private static float ele = STANDARD_CAMERA_ELE;
  private static float azi = STANDARD_CAMERA_AZI;

  private static boolean followAgent = false;
  private static AbstractAgent3D<?> agentToFollow = null;

  private static Vector3f cameraPosition = new Vector3f(0f, 0f, 0f);

  private static Vector3f cameraTargetPosition = new Vector3f(0f, 0f, 0f);

  private static int forwardAxis = 2;

  private final static Transform m = new Transform();

  private static int glutScreenWidth = 0;
  private static int glutScreenHeight = 0;

  private static Vector3f wireColor = new Vector3f();

  private long lastTime;
  private int frames = 0;
  private int lastFrames = 0;

  private int windowWidth = 1024;
  private int windowHeight = 768;
  private double mouseSensitivityX = 1;
  private double mouseSensitivityY = 0.35;
  private double mouseSensitivityW = 0.1;

  private static LwjglGL gl = new LwjglGL();
  private static boolean quit = false;
  private static String title = "videoplugin3d ";
 
  private static boolean mouseControlsActive = true;
 
  public static void setDynamicsWorld(DynamicsWorld dynamicsWorldToBeDrawn) {
    dynamicsWorld = dynamicsWorldToBeDrawn;
  }
 
  /**
   * Allow or disallow controls.
   * @param active Boolean: true - allow controls. false - disallow them.
   */
  public static void setMouseControls(boolean active) {
    mouseControlsActive = active;
  }
 
  @Override
  public List<String> getRequiredPlugins() {
    return null;
  }

  @Override
  public List<SingleParameter> getParameters() {
    ArrayList<SingleParameter> list = new ArrayList<SingleParameter>();

    list.add(new SingleParameter("windowWidth", Datatypes.INTEGER, 1024,
        "Breite des Fensters (1024, " + "falls nichts angegeben).",
        this.id().toUpperCase()));

    list.add(new SingleParameter("windowHeight", Datatypes.INTEGER, 768,
        "Höhe des Fensters (768, " + "falls nichts angegeben).", this
            .id().toUpperCase()));

    list.add(new SingleParameter("mouseSensitivityX", Datatypes.DOUBLE,
        1.0, "Mausempfindlichkeit horizontal.", this.id().toUpperCase()));

    list.add(new SingleParameter("mouseSensitivityY", Datatypes.DOUBLE,
        0.35, "Mausempfindlichkeit vertikal.", this.id().toUpperCase()));

    list.add(new SingleParameter("mouseSensitivityW", Datatypes.DOUBLE,
        0.012, "Mausempfindlichkeit Scrollrad.", this.id()
            .toUpperCase()));
    list.add(new SingleParameter("standardCameraDistance", Datatypes.DOUBLE,
        50.0, "Entfernung der Kamera vom zu beobachtenden Objekt.", this.id().toUpperCase()));

    return list;
  }

  @Override
  public String id() {
    return "videoplugin3d";
  }

  @Override
  public void runBeforeSimulation(
      final AbstractEnvironment3D<AbstractAgent3D<?>> env,
      final ParCollection params) {
   
    pfad = params.getStdDirectory();
   
    // Get the physics world to be drawn on screen.
    dynamicsWorld = env.getDynamicsWorld();
   
    // Store params locally.
    this.windowWidth = params.getParValueInt("windowWidth");
    this.windowHeight = params.getParValueInt("windowHeight");
    this.mouseSensitivityX = params.getParValueDouble("mouseSensitivityX");
    this.mouseSensitivityY = params.getParValueDouble("mouseSensitivityY");
    this.mouseSensitivityW = params.getParValueDouble("mouseSensitivityW");
    STANDARD_CAMERA_DISTANCE = params.getParValueDouble("standardCameraDistance").floatValue();

    // Create new display.

    if (this.windowHeight <= 0) {
        this.windowHeight = 400;
    }
    if (this.windowWidth <= 0) {
        this.windowWidth = 400;
    }
   
    try {
      Display.destroy();
    }
    catch (Exception e) {
     
    }
   
    try {
      Display.setDisplayMode(new DisplayMode(windowWidth, windowHeight));
      Display.setTitle(title);
      Display.create();
    } catch (LWJGLException e) {
      e.printStackTrace();
    }

    myinit();

    reshape(windowWidth, windowHeight);
    setCameraDistance(STANDARD_CAMERA_DISTANCE);
    //clientResetScene();

    lastTime = System.currentTimeMillis();
    Mouse.setGrabbed(true);

  }

  @Override
  public void runAfterSimulation(
      final AbstractEnvironment3D<AbstractAgent3D<?>> env,
      final ParCollection params) {

  }

  @Override
  public void runDuringSimulation(
      final AbstractEnvironment3D<AbstractAgent3D<?>> env, Wink simZyk,
      final ParCollection params) {

    clientMoveAndDisplay();
    Display.update();

    while (Keyboard.next()) {
      if (Keyboard.getEventCharacter() != '\0') {
        keyboardCallback(Keyboard.getEventCharacter());
      }
      if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE)
        quit = true;
      if (Keyboard.getEventKey() == Keyboard.KEY_Q)
        quit = true;
    }
   
    float dx = Mouse.getDX();
    float dy = Mouse.getDY();
    float dw = Mouse.getDWheel();
   
    if (mouseControlsActive) {     
    stepHorizontalBySteps(dx * mouseSensitivityX);
    stepVerticalBySteps(dy * mouseSensitivityY);
    zoomBySteps(dw * mouseSensitivityW);
    }
    // Calculate frame-rate.
    long time = System.currentTimeMillis();
    if (time - lastTime < 1000) {
      frames++;
    } else {
      lastFrames = frames;
      lastTime = time;
      frames = 0;
    }

    Display.setTitle(
        title + " | Tick: " +
        simZyk + " | Duration: " + clock.getTimeMilliseconds()/100/10.0 +
        "s | FPS: " + lastFrames);

    if (quit) {
      env.getSimTime().timeTerminate();
    }

  }

  @Override
  public void handleEvent(EASEvent e,
      final AbstractEnvironment3D<AbstractAgent3D<?>> env,
      Wink lastTimeStep, final ParCollection params) {
  }

  public void setOrthographicProjection() {
    // switch to projection mode
    gl.glMatrixMode(GL_PROJECTION);

    // save previous matrix which contains the
    // settings for the perspective projection
    gl.glPushMatrix();
    // reset matrix
    gl.glLoadIdentity();
    // set a 2D orthographic projection
    gl.gluOrtho2D(0f, glutScreenWidth, 0f, glutScreenHeight);
    gl.glMatrixMode(GL_MODELVIEW);
    gl.glLoadIdentity();
    // invert the y axis, down is positive
    gl.glScalef(1f, -1f, 1f);
    // mover the origin from the bottom left corner
    // to the upper left corner
    gl.glTranslatef(0f, -glutScreenHeight, 0f);
  }

  public void resetPerspectiveProjection() {
    gl.glMatrixMode(GL_PROJECTION);
    gl.glPopMatrix();
    gl.glMatrixMode(GL_MODELVIEW);
    updateCamera();
  }

  public float getDeltaTimeMicroseconds() {
    float dt = clock.getTimeMicroseconds();
    clock.reset();
    return dt;
  }

  public static void renderme() {
    updateCamera();

    if (dynamicsWorld != null) {
      int numObjects = dynamicsWorld.getNumCollisionObjects();
      wireColor.set(1f, 0f, 0f);
      for (int i = 0; i < numObjects; i++) {
        CollisionObject colObj = dynamicsWorld
            .getCollisionObjectArray().getQuick(i);
        RigidBody body = RigidBody.upcast(colObj);

        if (body != null && body.getMotionState() != null) {
          DefaultMotionState myMotionState = (DefaultMotionState) body
              .getMotionState();
          m.set(myMotionState.graphicsWorldTrans);
        } else {
          colObj.getWorldTransform(m);
        }

        wireColor.set(1f, 1f, 0.5f); // wants deactivation
        if ((i & 1) != 0) {
          wireColor.set(0f, 0f, 1f);
        }

        // color differently for active, sleeping, wantsdeactivation
        // states
        if (colObj.getActivationState() == 1) // active
        {
          if ((i & 1) != 0) {
            // wireColor.add(new Vector3f(1f, 0f, 0f));
            wireColor.x += 1f;
          } else {
            // wireColor.add(new Vector3f(0.5f, 0f, 0f));
            wireColor.x += 0.5f;
          }
        }
        if (colObj.getActivationState() == 2) // ISLAND_SLEEPING
        {
          if ((i & 1) != 0) {
            // wireColor.add(new Vector3f(0f, 1f, 0f));
            wireColor.y += 1f;
          } else {
            // wireColor.add(new Vector3f(0f, 0.5f, 0f));
            wireColor.y += 0.5f;
          }
        }

        GLShapeDrawer.drawOpenGL(gl, m, colObj.getCollisionShape(),
            wireColor, 0);
      }
    }
    updateCamera();
  }

  public static void clientMoveAndDisplay() {
    gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // simple dynamics world doesn't handle fixed-time-stepping
    // float ms = getDeltaTimeMicroseconds();

    // step the simulation
    if (dynamicsWorld != null) {
      // dynamicsWorld.stepSimulation(ms / 1000000f);
      // optional but useful: debug drawing
      //dynamicsWorld.debugDrawWorld();
    }
    renderme();

  }

  public static void updateCamera() {
    gl.glMatrixMode(GL_PROJECTION);

    gl.glLoadIdentity();

    float rele = (float) Math.toRadians(ele);
    float razi = (float) Math.toRadians(azi);

    Quat4f rot = new Quat4f();
    // Quaternion für 2. Achse (y, also nach oben) berechnen
    // bei Drehung um "razi" im Bogenmaß. Entspricht Drehung
    // nach links und rechts.
    QuaternionUtil.setRotation(rot, cameraUp, razi);

    Vector3f eyePos = new Vector3f();
    eyePos.set(0f, 0f, 0f);

    // 3. Koordinate setzen für den Abstand. 3. Achse bzw. z ist nach vorne.
    VectorUtil.setCoord(eyePos, forwardAxis, -cameraDistance);

    Vector3f forward = new Vector3f();
    forward.set(eyePos.x, eyePos.y, eyePos.z);

    if (forward.lengthSquared() < BulletGlobals.FLT_EPSILON) {
      forward.set(1f, 0f, 0f);
    }

    Vector3f right = new Vector3f();
    right.cross(cameraUp, forward);
    Quat4f roll = new Quat4f();
    QuaternionUtil.setRotation(roll, right, -rele);

    Matrix3f tmpMat1 = new Matrix3f();
    Matrix3f tmpMat2 = new Matrix3f();
    tmpMat1.set(rot);
    tmpMat2.set(roll);
    tmpMat1.mul(tmpMat2);
    tmpMat1.transform(eyePos);

    cameraPosition.set(eyePos);

    if (glutScreenWidth > glutScreenHeight) {
      float aspect = glutScreenWidth / (float) glutScreenHeight;
      gl.glFrustum(-aspect, aspect, -1.0, 1.0, 1.0, 10000.0);
    } else {
      float aspect = glutScreenHeight / (float) glutScreenWidth;
      gl.glFrustum(-1.0, 1.0, -aspect, aspect, 1.0, 10000.0);
    }
   
    // Das Ziel neu setzen, so dass die Kamera neu ausgerichtet wird.
    if (followAgent && agentToFollow != null) {
      cameraTargetPosition = agentToFollow.getPosition();
    }

    gl.glMatrixMode(GL_MODELVIEW);
    gl.glLoadIdentity();

    // Verschiebe die Kamera in Richtung des zu beobachtenden Objekts.
    cameraPosition.add(cameraTargetPosition);

    gl.gluLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z,
        cameraTargetPosition.x, cameraTargetPosition.y,
        cameraTargetPosition.z, cameraUp.x, cameraUp.y, cameraUp.z);
  }

  public static void setCameraDistance(float dist) {
    cameraDistance = dist;
  }

  public DynamicsWorld getDynamicsWorld() {
    return dynamicsWorld;
  }

  public static void reshape(int w, int h) {
    glutScreenWidth = w;
    glutScreenHeight = h;
    gl.glViewport(0, 0, w, h);
    updateCamera();
  }

  public static void myinit() {
    float[] light_ambient = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
    float[] light_diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
    float[] light_specular = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
    /* light_position is NOT default value */
    float[] light_position0 = new float[] { 1.0f, 10.0f, 1.0f, 0.0f };
    float[] light_position1 = new float[] { -1.0f, -10.0f, -1.0f, 0.0f };

    gl.glLight(GL_LIGHT0, GL_AMBIENT, light_ambient);
    gl.glLight(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    gl.glLight(GL_LIGHT0, GL_SPECULAR, light_specular);
    gl.glLight(GL_LIGHT0, GL_POSITION, light_position0);

    gl.glLight(GL_LIGHT1, GL_AMBIENT, light_ambient);
    gl.glLight(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
    gl.glLight(GL_LIGHT1, GL_SPECULAR, light_specular);
    gl.glLight(GL_LIGHT1, GL_POSITION, light_position1);

    gl.glEnable(GL_LIGHTING);
    gl.glEnable(GL_LIGHT0);
    gl.glEnable(GL_LIGHT1);

    gl.glShadeModel(GL_SMOOTH);
    gl.glEnable(GL_DEPTH_TEST);
    gl.glDepthFunc(GL_LESS);

    gl.glClearColor(0.7f, 0.7f, 0.7f, 0f);

  }

  public void clientResetScene() {
    BulletStats.gNumDeepPenetrationChecks = 0;
    BulletStats.gNumGjkChecks = 0;

    int numObjects = 0;
    if (dynamicsWorld != null) {
      // dynamicsWorld.stepSimulation(1f / 60f, 0);
      numObjects = dynamicsWorld.getNumCollisionObjects();
    }

    for (int i = 0; i < numObjects; i++) {
      CollisionObject colObj = dynamicsWorld.getCollisionObjectArray()
          .getQuick(i);
      RigidBody body = RigidBody.upcast(colObj);
      if (body != null) {
        if (body.getMotionState() != null) {
          DefaultMotionState myMotionState = (DefaultMotionState) body
              .getMotionState();
          myMotionState.graphicsWorldTrans
              .set(myMotionState.startWorldTrans);
          colObj.setWorldTransform(myMotionState.graphicsWorldTrans);
          colObj.setInterpolationWorldTransform(myMotionState.startWorldTrans);
          colObj.activate();
        }
        // removed cached contact points
        dynamicsWorld
            .getBroadphase()
            .getOverlappingPairCache()
            .cleanProxyFromPairs(colObj.getBroadphaseHandle(),
                getDynamicsWorld().getDispatcher());

        body = RigidBody.upcast(colObj);
        if (body != null && !body.isStaticObject()) {
          RigidBody.upcast(colObj).setLinearVelocity(
              new Vector3f(0f, 0f, 0f));
          RigidBody.upcast(colObj).setAngularVelocity(
              new Vector3f(0f, 0f, 0f));
        }
      }
    }
  }

  public void stepLeft() {
    azi -= STEPSIZE;
    if (azi < 0) {
      azi += 360;
    }
    updateCamera();
  }

  public void stepRight() {
    azi += STEPSIZE;
    if (azi >= 360) {
      azi -= 360;
    }
    updateCamera();
  }

  public void stepUp() {
    ele += STEPSIZE;
    if (ele >= 360) {
      ele -= 360;
    }
    updateCamera();
  }

  public void stepDown() {
    ele -= STEPSIZE;
    if (ele < 0) {
      ele += 360;
    }
    updateCamera();
  }

  public void stepHorizontalBySteps(double stepSize) {
    azi -= (int) stepSize;
    if (azi < 0) {
      azi += 360;
    }
    updateCamera();
  }

  public void stepVerticalBySteps(double stepSize) {
    ele += (int) stepSize;
    if (ele >= 360) {
      ele -= 360;
    }
    updateCamera();
  }

  public void zoomIn() {
    cameraDistance -= 5f;
    updateCamera();
    if (cameraDistance < 0.1f) {
      cameraDistance = 0.1f;
    }
  }

  public void zoomOut() {
    cameraDistance += 5f;
    updateCamera();
  }

  public void zoomBySteps(double stepsize) {
    cameraDistance -= (int) stepsize;
    updateCamera();
    if (cameraDistance < 0.1f) {
      cameraDistance = 0.1f;
    }
  }

  /*
   * Resets the camera's position.
   */
  public static void resetCamera() {
    cameraDistance = STANDARD_CAMERA_DISTANCE;
    azi = STANDARD_CAMERA_AZI;
    ele = STANDARD_CAMERA_ELE;
    cameraPosition = new Vector3f(0, 0, 0);
    updateCamera();
  }

  /*
   * public void setCameraUp(Vector3f camUp) { cameraUp.set(camUp); }
   *
   * public void setCameraForwardAxis(int axis) { forwardAxis = axis; }
   */

  public Vector3f getCameraPosition() {
    return cameraPosition;
  }

  public Vector3f getCameraTargetPosition() {
    return cameraTargetPosition;
  }

  public static void setCameraTargetPosition(Vector3f target) {
    followAgent = false;
    agentToFollow = null;
    cameraTargetPosition = target;
  }

  public static void setCameraToFollowAgentPosition(AbstractAgent3D<?> agent) {
    followAgent = true;
    agentToFollow = agent;
    cameraTargetPosition = agent.getPosition();
  }

  private void keyboardCallback(char key) {
    switch (key) {
    case 'a':
      stepLeft();
      break;
    case 'd':
      stepRight();
      break;
    case 'w':
      stepUp();
      break;
    case 's':
      stepDown();
      break;
    case 'y':
      zoomIn();
      break;
    case 'x':
      zoomOut();
      break;
    case ' ':
      resetCamera();
      break;
    case 'b':
      saveScreenshot();
      break;
    default:
      break;
    }
  }

  /**
   * Returns a BufferedImage of the current scene. Use with care (slows down
   * the simulation!).
   *
   * @return BufferedImage of the current scene.
   */
  public static BufferedImage getBufferedImage() {

    int frameWidth = Display.getDisplayMode().getWidth();
    int frameHeight = Display.getDisplayMode().getHeight();

    BufferedImage screenshot = null;
    // allocate space for RBG pixels
    ByteBuffer fb = ByteBuffer.allocateDirect(frameWidth * frameHeight * 3);

    int[] pixels = new int[frameWidth * frameHeight];
    int bindex;

    // grab a copy of the current frame contents as RGB
    /*
    GL11.glReadPixels(0, 0, frameWidth, frameHeight, GL11.GL_RGB,
        GL11.GL_UNSIGNED_BYTE, fb);*/
    // GL_BYTE statt GL_UNSIGNED_BYTE, später *2 wg. Bug!
    GL11.glReadPixels(0, 0, frameWidth, frameHeight, GL11.GL_RGB,
        GL11.GL_BYTE, fb);

    // convert RGB data in ByteBuffer to integer array
    for (int i = 0; i < pixels.length; i++) {
      bindex = i * 3;
    // *2, wg. Bug 
      pixels[i] = ((fb.get(bindex + 0)*2 << 16)) + ((fb.get(bindex + 1)*2 << 8))
          + ((fb.get(bindex + 2)*2 << 0));
    }

    // Create a BufferedImage with the RGB pixels
    try {
      screenshot = new BufferedImage(frameWidth, frameHeight,
          BufferedImage.TYPE_INT_RGB);
      screenshot.setRGB(0, 0, frameWidth, frameHeight, pixels, 0,
          frameWidth);

      // * Flip Image Y Axis *
      AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
      tx.translate(0, -screenshot.getHeight(null));
      AffineTransformOp op = new AffineTransformOp(tx,
          AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
      screenshot = op.filter(screenshot, null);

    } catch (Exception e) {
      System.out.println("ScreenShot exception: " + e);
    }
    return screenshot;
  }

  /*
   * Take a screenshot and save it as png.
   */
  public static void saveScreenshot() {
    try {
      Calendar c = new GregorianCalendar();
      String path = pfad + File.separator;
         
      File file = new File(path + "VideoPlugin3D-Screenshot-"
          + c.get(Calendar.YEAR) + "-"
          + (c.get(Calendar.MONTH)+1) + "-"
          + c.get(Calendar.DAY_OF_MONTH) + "-"
          + c.get(Calendar.HOUR_OF_DAY) + "-"
          + c.get(Calendar.MINUTE) + "-"
          + c.get(Calendar.SECOND)
          + ".png");
      ImageIO.write(getBufferedImage(), "png", file);
      System.out.print("\nScreenshot saved to ");
      System.out.println(file.getAbsolutePath());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

    @Override
    public List<String> getSupportedPlugins() {
        return null;
    }

    @Override
    public void onSimulationResumed(AbstractEnvironment3D<AbstractAgent3D<?>> env, Wink resumeTime,
            ParCollection params) {
       
    }
}
TOP

Related Classes of eas.plugins.standard.visualization.visualization3D.VideoPlugin3D

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.