/*
* Copyright 2010 Ian Bollinger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.worcester.subter;
import java.awt.AWTEvent;
import java.awt.event.KeyEvent;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.PickInfo;
import javax.media.j3d.Transform3D;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import com.sun.j3d.utils.behaviors.vp.ViewPlatformBehavior;
import com.sun.j3d.utils.pickfast.PickTool;
import edu.worcester.subter.j3d.Transforms;
public final class KeyBehavior extends ViewPlatformBehavior {
private static final double MOVE_AMOUNT = 0.1;
private static final double ROTATION_AMOUNT = Math.PI / 64.0;
private static final Vector3d FORWARD_VECTOR = new Vector3d(0, 0,
-MOVE_AMOUNT);
private static final Vector3d BACKWARD_VECTOR = new Vector3d(0, 0,
MOVE_AMOUNT);
private static final int FORWARD_KEY = KeyEvent.VK_UP;
private static final int BACK_KEY = KeyEvent.VK_DOWN;
private static final int LEFT_KEY = KeyEvent.VK_LEFT;
private static final int RIGHT_KEY = KeyEvent.VK_RIGHT;
private WakeupCriterion keyPress;
private final BranchGroup bg;
private PickTool pickTool;
public KeyBehavior(BranchGroup bg) {
super();
this.bg = bg;
}
private void doRotateY(double radians) {
final Transform3D transform3D = Transforms.getTransform(targetTG);
transform3D.mul(Transforms.rotY(radians));
targetTG.setTransform(transform3D);
}
@Override
public void initialize() {
keyPress = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
wakeupOn(keyPress);
pickTool = new PickTool(bg);
pickTool.setMode(PickInfo.PICK_GEOMETRY);
}
private void moveBy(Vector3d theMove) {
final Transform3D transform3D = Transforms.getTransform(targetTG);
final Vector3d start = Transforms.getVector3d(transform3D);
transform3D.mul(Transforms.translation(theMove));
final Transform3D transform2 = new Transform3D(transform3D);
final Vector3d theMove2 = new Vector3d(theMove);
theMove2.scale(5.0);
transform2.mul(Transforms.translation(theMove2));
final Vector3d stop = Transforms.getVector3d(transform2);
pickTool.setShapeSegment(new Point3d(start), new Point3d(stop));
if (pickTool.pickClosest() == null) {
targetTG.setTransform(transform3D);
}
}
private void processKeyEvent(KeyEvent eventKey) {
switch (eventKey.getKeyCode()) {
case FORWARD_KEY:
moveBy(FORWARD_VECTOR);
break;
case BACK_KEY:
moveBy(BACKWARD_VECTOR);
break;
case LEFT_KEY:
doRotateY(ROTATION_AMOUNT);
break;
case RIGHT_KEY:
doRotateY(-ROTATION_AMOUNT);
}
}
@Override
public void processStimulus(
@SuppressWarnings("rawtypes") Enumeration criteria) {
@SuppressWarnings("unchecked")
final List<? extends WakeupCriterion> list = Collections.list(criteria);
for (final WakeupCriterion criterion : list) {
if (criterion instanceof WakeupOnAWTEvent) {
final WakeupOnAWTEvent wakeup = (WakeupOnAWTEvent) criterion;
for (final AWTEvent e : wakeup.getAWTEvent()) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
processKeyEvent((KeyEvent) e);
}
}
wakeupOn(keyPress);
}
}
}
}