WASDBehavior (Java3D)

23 Nov 2009

Update (Nov 25, 2009): I uploaded a slightly improved version of the class. The processing of FOCUS_LOST events was added.

This weekend I was working on improving the camera positioning/movement in the terrain LOD tool presented before. The classes shipped within Java3D did not really fit my needs. I experimented with MouseRotate and KeyNavigatorBehavior, but the results were suboptimal at best – maybe I missed something.

I envisioned a camera movement that is similar to movement in computer games: translation using W, A, S, D and rotation using the mouse. Translation is relative to the current view direction, i.e. forward moving (W) results in a translation along the view direction. A and D result in moving sideway (strafing).

Rotation is controlled using the relative movement of the mouse. At the moment it should take place when the mouse is dragged, i.e. the left mouse button is pressed. Moving the mouse upwards/downwards leads to a view direction rotation upwards/downwards. In a similar way left/right mouse movement leads to left/right rotation. Rotation around the view direction can be performed using the Q and E keys.

Instead of using the standard Behavior classes of Java3D, I implemented a new Behavior, the WASDBehavior. It seems to work quite well (mouse rotation appears a little gradual on closer inspection). The WASDBehavior incorporates both translation and rotation as described before. I decided to share my work with anyone who is in need of such a camera movement Behavior for Java3D. The source code can be downloaded right here:

For now I won’t go into the details of the source code. Check the comments in the source file to learn more about what I’ve done. For those who just want to try this class: Add the class to your project, import it into your scene graph construction class and add something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// m_Universe is the SimpleUniverse object.
ViewingPlatform vp = m_Universe.getViewingPlatform();
TransformGroup tgVP = vp.getViewPlatformTransform();

// The second parameter is the left-right rotation axis. You can just pass null
// to take the viewing platform up direction as the left-right rotation axis.
// The option to specify this axis was introduced to allow a more natural
// left/right rotation.
WASDBehavior wasd = new WASDBehavior(tgVP, new Vector3d(0, 1, 0));
wasd.setSchedulingBounds(new BoundingSphere());
// Initial viewing platform transformation parameters. This method takes the
// same arguments as the Transform3D.lookAt(..) method (eye point, lookat
// point, up direction). The up direction is normalized internally.
wasd.setEyeParameters(
	new Point3d(0, 0.6, 0.6), new Point3d(0, 0, 0), new Vector3d(0, -1, 1));
		   
// scene is the main BranchGroup.
scene.addChild(wasd);

I’m thinking about adding an option for rotation without the need to press the mouse button. Another extension could be some methods to specify the keys used to perform the movement. If there is enough interest, I’ll gladly extend this class.