Package org.osm2world.viewer.control.navigation

Source Code of org.osm2world.viewer.control.navigation.DefaultNavigation

package org.osm2world.viewer.control.navigation;

import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.util.HashSet;
import java.util.Set;

import javax.swing.Timer;
import javax.swing.event.MouseInputListener;

import org.osm2world.core.math.VectorXYZ;
import org.osm2world.core.target.common.rendering.Camera;
import org.osm2world.viewer.model.RenderOptions;
import org.osm2world.viewer.view.ViewerFrame;


public class DefaultNavigation extends MouseAdapter implements KeyListener, MouseInputListener {

  private final static double ANGLE_INCREMENT = Math.PI/200;
  private final static double MOVEMENT_INCREMENT = 2.0;
 
  private final RenderOptions renderOptions;
  private final ViewerFrame viewerFrame;

  private final Timer timer;
 
  public DefaultNavigation(ViewerFrame viewerFrame, RenderOptions renderOptions) {
   
    this.viewerFrame = viewerFrame;
    this.renderOptions = renderOptions;
   
    timer = new Timer(20, KEYBOARD_TASK);
  }
 
  private boolean translationDrag = false;
  private boolean rotationDrag = false;
  private boolean movementDrag = false;
 
  private Point previousMousePoint;

  private final Set<Integer> pressedKeys = new HashSet<Integer>();

  @Override
  public void keyPressed(KeyEvent e) {
    synchronized (pressedKeys) {
      pressedKeys.add(e.getKeyCode());
      timer.start();
    }
  }

  @Override
  public void keyReleased(KeyEvent e) {
    synchronized (pressedKeys) {
      pressedKeys.remove(e.getKeyCode());
      if (pressedKeys.isEmpty())
        timer.stop();
    }
  }
 
  @Override
  public void keyTyped(KeyEvent e) {}
 
  @Override
  public void mouseDragged(MouseEvent e) {
   
    Point currentMousePoint = e.getPoint();
   
    float movementX = currentMousePoint.x - previousMousePoint.x;
    float movementY = currentMousePoint.y - previousMousePoint.y;
   
    Camera camera = renderOptions.camera;
   
    if (camera != null) {
 
      if (translationDrag) {
       
        camera.moveMapForward(movementY);
        camera.moveMapRight(movementX);
       
      } else if (rotationDrag) {
         
        /* view left/right */
        camera.rotateY(movementX/100);
       
        /* view up/down */
        camera.mapPitch(movementY/-100);
     
      } else if (movementDrag) {
       
        /* roll left/right */
        camera.roll(movementX/100);
       
        /* move up/down */
        camera.moveMapUp(movementY);
      }
    }
     
    previousMousePoint = currentMousePoint;
     
  }
 
  @Override
  public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
      viewerFrame.setCursor(new Cursor(Cursor.MOVE_CURSOR));
      translationDrag = true;
    } else if (e.getButton() == MouseEvent.BUTTON2) {
      viewerFrame.setCursor(new Cursor(Cursor.MOVE_CURSOR));
      movementDrag = true;
    } else {
      viewerFrame.setCursor(new Cursor(Cursor.MOVE_CURSOR));
      rotationDrag = true;
    }
    previousMousePoint = e.getPoint();
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    viewerFrame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    translationDrag = false;
    rotationDrag = false;
    movementDrag = false;
  }
 
  @Override
  public void mouseWheelMoved(MouseWheelEvent e) {

    zoom(e.getWheelRotation() < 0, 1);
  }

  private void zoom(boolean zoomIn, double scale) {
    Camera c = renderOptions.camera;
   
    if (c != null) {

      VectorXYZ toLookAt = c.getLookAt().subtract(c.getPos());
      VectorXYZ move = toLookAt.mult(scale * (zoomIn ? 0.2f : -0.25f));
      VectorXYZ newPos = c.getPos().add(move);

      c.setPos(newPos);
    }
  }
 
  private final ActionListener KEYBOARD_TASK = new ActionListener() {
   
    @Override
    public void actionPerformed(ActionEvent e) {

      Camera c = renderOptions.camera;

      if (c != null) {

        synchronized (pressedKeys) {

          for (int key : pressedKeys) {

            switch (key) {
            case KeyEvent.VK_Q:
              c.roll(ANGLE_INCREMENT);
              break;
            case KeyEvent.VK_E:
              c.roll(-ANGLE_INCREMENT);
              break;
            case KeyEvent.VK_W:
              c.moveForward(MOVEMENT_INCREMENT);
              break;
            case KeyEvent.VK_S:
              c.moveForward(-MOVEMENT_INCREMENT);
              break;
            case KeyEvent.VK_A:
              c.moveRight(MOVEMENT_INCREMENT);
              break;
            case KeyEvent.VK_D:
              c.moveRight(-MOVEMENT_INCREMENT);
              break;
            case KeyEvent.VK_PAGE_UP:
              c.moveUp(MOVEMENT_INCREMENT);
              break;
            case KeyEvent.VK_PAGE_DOWN:
              c.moveUp(-MOVEMENT_INCREMENT);
              break;
            case KeyEvent.VK_UP:
              c.pitch(ANGLE_INCREMENT);
              break;
            case KeyEvent.VK_DOWN:
              c.pitch(-ANGLE_INCREMENT);
              break;
            case KeyEvent.VK_RIGHT:
              c.yaw(ANGLE_INCREMENT);
              break;
            case KeyEvent.VK_LEFT:
              c.yaw(-ANGLE_INCREMENT);
              break;
            case KeyEvent.VK_PLUS:
            case KeyEvent.VK_I:
              zoom(true, 0.5);
              break;
            case KeyEvent.VK_MINUS:
            case KeyEvent.VK_O:
              zoom(false, 0.5);
              break;
            }
          }
        }
      }
    }
  };
}
TOP

Related Classes of org.osm2world.viewer.control.navigation.DefaultNavigation

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.