To make our cube controllable we simple need to update its behavior. Instead of reacting to the frame being drawn we'll change it so it wakes up when a key is pressed.
/**
* The intialiser is called at the start of the universe
* and needs to set up the original coniditon that this
* object will wake up on
*/
public void initialize() {
setSchedulingBounds(new BoundingSphere(new Point3d(0,0,0),100));
wakeupOn(new WakeupOnAWTEvent(AWTEvent.KEY_EVENT_MASK));
}
Here we've updated the wake up condition to a WakeupOnAWTEvent. AWT is the base Java window toolkit (Abstract Windowing Toolkit). It handles all events from the keyboard, mouse, etc. In this case we've scheduled the event to wake up when an matching KEY_EVENT_MASK is fired, i.e. when a key is pressed. As before the processStimulus method will be called when this happens.
/**
* Each time the wake up condition is met, this method is called
* with a list of the reasons it was woken (e.g. the met conditions)
*
* @param enumeration The list of condition met
*/
public void processStimulus(Enumeration enumeration) {
// reschedule the wake up
wakeupOn(new WakeupOnAWTEvent(AWTEvent.KEY_EVENT_MASK));
// grab the event that cause this call
// we can assume its a single key event, since thats all we requested
KeyEvent event = (KeyEvent) ((WakeupOnAWTEvent) enumeration.nextElement()).getAWTEvent()[0];
// add a little to the rotation
if (event.getKeyCode() == KeyEvent.VK_LEFT) {
rotationY -= 3;
}
if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
rotationY += 3;
}
if (event.getKeyCode() == KeyEvent.VK_UP) {
rotationX -= 3;
}
if (event.getKeyCode() == KeyEvent.VK_DOWN) {
rotationX += 3;
}
// update the transform affecting this shape
transformX.setIdentity();
transformX.rotX(Math.toRadians(rotationX));
transformY.setIdentity();
transformY.rotY(Math.toRadians(rotationY));
// now multiply the transforms together to form one transform
// which we'll apply
transformX.mul(transformY);
tg.setTransform(transformX);
}
Our final update is to the processStimulus method. First off we now reschedule the behavior against the key event. Next we retrieve the key event from the enumeration passed in. We can assume the cast to (KeyEvent) since this is the only type of event we're scheduled to retrieve. The next few lines check the key pressed against the the cursor keys, updating rotation values if the appropriate key was pressed.
Finally, at the bottom of the method we need to account for our two steps of rotation. We're now going to support rotating on the X and Y axis. To achieve this we build two transforms, one for the X axis and one for the Y axis. To combine the two transforms we multiply them together using transformX.mul(transformY). We then apply this as before.
And thats it! We now have a 3d model in space (albeit a cube) which we can control with the keyboard. This will hopefully form a basis for future projects.