⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboardinputdevice.java

📁 Java 3D Desktop Environment旨在使用Java 3D来创建一个3D桌面环境。功能包括:分布式的应用程序
💻 JAVA
字号:
/* * Copyright (c) 2000, Niklas Mehner  * All rights reserved. *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met: *  *   - Redistributions of source code must retain the above copyright  *     notice, this list of conditions and the following disclaimer. *  *   - Redistributions in binary form must reproduce the above copyright  *     notice, this list of conditions and the following disclaimer in  *     the documentation and/or other materials provided with the  *     distribution. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */ package org.j3de.input;                 

import java.awt.AWTEvent;
import java.awt.event.KeyEvent;
import java.util.Enumeration;
import java.util.Map;
import java.util.Hashtable;
 
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Behavior;
import javax.media.j3d.InputDevice;
import javax.media.j3d.Sensor;
import javax.media.j3d.Transform3D;  
import javax.media.j3d.WakeupCondition;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOr;

import javax.vecmath.Point3d;
import javax.vecmath.Matrix3d;
import javax.vecmath.Vector3f;   

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Document;     
import org.w3c.dom.Element;

import org.j3de.exception.ExceptionHandler;
import org.j3de.util.AbstractComponent;  
import org.j3de.util.ConfigurationException;  
import org.j3de.util.EntryFactory;

public class KeyboardInputDevice extends AbstractComponent implements InputDevice, HasBehavior {  
  private static int[] BUTTONS = new int[0];  
  
  private Sensor sensor;
  private int processingMode;   
  private Transform3D transform;  
  private Vector3f position;
  private WakeupCondition keyCriterion;
  private Map actions;
  private Map keyAssignment;
  private float currentSpeed;
  private float turnAngle;
  
  public KeyboardInputDevice() {  
    this.sensor  = new Sensor(this);         
    processingMode = InputDevice.DEMAND_DRIVEN;  
    transform = new Transform3D();    
    position = new Vector3f();
    currentSpeed = 1.0f; 
    keyAssignment = new Hashtable();  
    position = new Vector3f();
    createActions();
  } 
  
  public synchronized void createActions() { 
    actions = new Hashtable();
    actions.put("move_forward" , new MoveKeyAction(2, -1.0f));
    actions.put("move_backward", new MoveKeyAction(2,  1.0f));
    actions.put("move_left"    , new MoveKeyAction(0, -1.0f));
    actions.put("move_right"   , new MoveKeyAction(0,  1.0f));
    actions.put("move_up"      , new MoveKeyAction(1,  1.0f));
    actions.put("move_down"    , new MoveKeyAction(1, -1.0f));
    actions.put("roll_right"   , new TurnKeyAction(2,  1.0f));
    actions.put("roll_left"    , new TurnKeyAction(2, -1.0f));
    actions.put("turn_left"    , new TurnKeyAction(1, -1.0f));
    actions.put("turn_right"   , new TurnKeyAction(1,  1.0f));
    actions.put("turn_up"      , new TurnKeyAction(0, -1.0f));
    actions.put("turn_down"    , new TurnKeyAction(0,  1.0f));
    actions.put("speed_up"     , new SpeedKeyAction(2.0f));
    actions.put("speed_down"   , new SpeedKeyAction(0.5f));
  }
  
  public boolean initialize() { 
    return true;
  }
  
  public void setNominalPositionAndOrientation() {
    // TODO implement 
  }  
  
  public void pollAndProcessInput() {   
    sensor.setNextSensorRead(System.currentTimeMillis(), transform, BUTTONS);
  }
  
  public synchronized void processStreamInput() {  
    // According to j3d documentation this should remain an empty method ...
  }
  
  public void close() {  
    // nothing to do ...
  }
  
  public int getProcessingMode() {                           
    return processingMode;
  }
  
  public void setProcessingMode(int mode) {   
    this.processingMode = mode; 
  }
  
  public int getSensorCount() {
    return 1;
  }
  
  public Sensor getSensor(int sensorIndex) {  
    return sensor;
  }
  
  private void processKeyEvent(KeyEvent event) {         Integer key = new Integer(event.getKeyCode());
    
    KeyAction action = (KeyAction)keyAssignment.get(key);
    
    if (action != null) {
      if (event.getID() == KeyEvent.KEY_PRESSED) {
        action.keyPressed();
      } else if (event.getID() == KeyEvent.KEY_RELEASED) {
        action.keyReleased();
      }
    }
    
  }       
  
  public void configure(Node node, Document nodeFactory)  throws ConfigurationException {  
    super.configure(node, nodeFactory);    
    
    turnAngle = helper.getPropertyValue("TurnDegrees", 30, true);
    
    helper.getList("keyassignment", 
      new EntryFactory() {
        public Object createEntry(Node node) {
          try {
            NamedNodeMap attributes = node.getAttributes();    
            String name = attributes.getNamedItem("name").getNodeValue();
            String value = attributes.getNamedItem("value").getNodeValue(); 
            
            Integer keyvalue  = (Integer)KeyEvent.class.getDeclaredField("VK_" + name).get(null);
            Object  keyaction = actions.get(value);
            
            keyAssignment.put(keyvalue, keyaction);   
            return null;
          } catch (Exception e) {
            ExceptionHandler.handleException(e);
            return null;
          }
        }
      });  
  }  

  
  public Behavior getBehavior() {     
    return new Behavior() {  
    
      public void initialize() {
        setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0));
        
        WakeupCriterion[] keyEvents = new WakeupCriterion[2];

        keyEvents[0] = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
        keyEvents[1] = new WakeupOnAWTEvent(KeyEvent.KEY_RELEASED);
        keyCriterion = new WakeupOr(keyEvents);
        wakeupOn(keyCriterion); 
      } 
   
      public synchronized void processStimulus(Enumeration criteria) {     
        WakeupCriterion wakeup;
        AWTEvent[] event;
      
        while(criteria.hasMoreElements()) {
          wakeup = (WakeupCriterion) criteria.nextElement();
        
          if( !(wakeup instanceof WakeupOnAWTEvent) )
            continue;
      
          event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
          for (int i=0; i<event.length; i++) {
            if ((event[i].getID() == KeyEvent.KEY_PRESSED) || 
                (event[i].getID() == KeyEvent.KEY_RELEASED)) {
              processKeyEvent((KeyEvent)event[i]);
            }
          }
        }
        wakeupOn(keyCriterion);
      } 
    }; 
    
  } 
  
  private class MoveKeyAction implements KeyAction {
    int    index;                       
    float faktor;
    
    public MoveKeyAction(int index, float faktor) {
      this.index = index;
      this.faktor = faktor;
    }
    
    public void keyPressed() { 
      if (index == 0) {
        position.x = currentSpeed * faktor;
      } else if (index == 1) {
        position.y = currentSpeed * faktor;
      } else if (index == 2) {
        position.z = currentSpeed * faktor;
      } 
      
      transform.set(position);
    }
    
    public void keyReleased() {
      if (index == 0) {
        position.x = 0;
      } else if (index == 1) {
        position.y = 0;
      } else if (index == 2) {
        position.z = 0;
      } 
      
      transform.set(position);
    }
  }
  
  private Matrix3d transformX;
  private Matrix3d transformY;
  private Matrix3d transformZ;
  private Matrix3d result;    

  private class TurnKeyAction implements KeyAction {    
    private int    index;                       
    private double direction;
    
    public TurnKeyAction(int index, double direction) {
      this.index = index;
      this.direction = direction;  
      transformX = new Matrix3d();  
      transformX.setIdentity();  
      transformY = new Matrix3d();
      transformY.setIdentity();  
      transformZ = new Matrix3d();
      transformZ.setIdentity();  
      result     = new Matrix3d();
    }                  
    
    private void updateTransform() {
      result.setIdentity();     
     
      result.mul(transformX); 
      result.mul(transformY);
      result.mul(transformZ);
      transform.set(result);
    }
    
    public void keyPressed() {               
      if (index == 0) {
        transformX.rotX(turnAngle * direction);
      } else if (index == 1) {
        transformY.rotY(turnAngle * direction);
      } else if (index == 2) {
        transformZ.rotZ(turnAngle * direction);
      } 
      
      updateTransform();
    }
    
    public void keyReleased() {
      if (index == 0) {
        transformX.setIdentity();
      } else if (index == 1) {
        transformY.setIdentity();
      } else if (index == 2) {
        transformZ.setIdentity();
      } 
      
      updateTransform();
    }
  }

  private class SpeedKeyAction implements KeyAction {
    private float faktor;
    
    public SpeedKeyAction(float faktor) {
      this.faktor = faktor;
    }
    
    public void keyPressed() {  
      currentSpeed *= faktor;
    }
    
    public void keyReleased() {
      currentSpeed /= faktor;
    }
  }
  
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -