import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashSet;
import java.util.Set;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Light;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
class ObjectRotator implements KeyListener
{
private final TransformGroup rotatedTransformGroup;
private final int upKey = KeyEvent.VK_UP;
private final int downKey = KeyEvent.VK_DOWN;
private final int leftKey = KeyEvent.VK_LEFT;
private final int rightKey = KeyEvent.VK_RIGHT;
private float speed = 0.05f;
private final Set<Integer> pressedKeys = new HashSet<Integer>();
private Matrix4f currentRotation = new Matrix4f();
public ObjectRotator(TransformGroup rotatedTransformGroup)
{
this.rotatedTransformGroup = rotatedTransformGroup;
currentRotation.setIdentity();
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
while (true)
{
updateMovement();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
t.setDaemon(true);
t.start();
}
private void updateMovement()
{
if (pressedKeys.contains(upKey))
{
rotate(-speed, 0);
}
else if (pressedKeys.contains(downKey))
{
rotate(speed, 0);
}
else if (pressedKeys.contains(leftKey))
{
rotate(0, -speed);
}
else if (pressedKeys.contains(rightKey))
{
rotate(0, speed);
}
}
private void rotate(float angleX, float angleY)
{
Matrix4f m0 = new Matrix4f();
m0.setIdentity();
m0.rotX(angleX);
Matrix4f m1 = new Matrix4f();
m1.setIdentity();
m1.rotY(angleY);
Matrix4f result = new Matrix4f();
result.mul(m0, m1);
currentRotation.mul(result, currentRotation);
Transform3D t = new Transform3D(currentRotation);
rotatedTransformGroup.setTransform(t);
}
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e)
{
pressedKeys.add(e.getKeyCode());
}
@Override
public void keyReleased(KeyEvent e)
{
pressedKeys.remove(e.getKeyCode());
}
}
public class RotationExample extends JFrame
{
public RotationExample()
{
setFocusable(true);
setSize(600,600);
setPreferredSize(getSize());
setLayout(new BorderLayout());
create3D();
setVisible(true);
}
private void create3D() {
Canvas3D canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
SimpleUniverse su = new SimpleUniverse(canvas3D);
su.getViewingPlatform().setNominalViewingTransform();
BranchGroup root = new BranchGroup();
TransformGroup rootTG = new TransformGroup();
root.addChild(rootTG);
rootTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
rootTG.addChild(createLight());
rootTG.addChild(new ColorCube(0.5f));
ObjectRotator objectRotator = new ObjectRotator(rootTG);
addKeyListener(objectRotator);
su.addBranchGraph(root);
canvas3D.setFocusable(false);
add(canvas3D);
}
private static Light createLight()
{
Color3f lightColor = new Color3f(1.8f, 0.1f, 0.1f);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Vector3f lightDirection = new Vector3f(1.0f, -3.0f, -12.0f);
DirectionalLight light = new DirectionalLight(lightColor, lightDirection);
light.setInfluencingBounds(bounds);
return light;
}
public static void main(String[] args) {
new RotationExample();
}
}