Java3D Lights (Pyramid.java is same as Example2)
File: java3d/Lights/Main.java
import java.awt.*;
import javax.swing.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.keyboard.*;
import com.sun.j3d.utils.behaviors.vp.*;
import com.sun.j3d.utils.geometry.*;
/**
* Example using lighting
* R. Jacob 11/3/2006
*/
public class Main extends JFrame {
public static void main (String[] args) {
new Main();
}
public Main() {
/*
* Here, we really need our own canvas, and our own JFrame,
* so we can put some Swing widgets around the edge
*/
setSize (500, 500);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
/*
* Set up SimpleUniverse, with our own Canvas3D
*/
Canvas3D canvas3D = new Canvas3D (SimpleUniverse.getPreferredConfiguration());
SimpleUniverse universe = new SimpleUniverse (canvas3D);
Scene scene = new Scene ();
Lights lights = new Lights (scene);
addKbdNavig (universe, scene);
/*
* Install our scene graph
*/
scene.compile();
universe.addBranchGraph (scene);
/*
* Make a GUI layout in our JFrame,
* with the 3D canvas in the center
*/
Container content = getContentPane();
content.setLayout (new BorderLayout());
content.add (canvas3D, BorderLayout.CENTER);
/*
* Our buttons, each is connected to one of the lights we
* created in Scene
*/
JPanel panel = new JPanel ();
content.add (panel, BorderLayout.SOUTH);
panel.add (new LightButton (lights.getMainLight(), "Main light"));
panel.add (new LightButton (lights.getFillLight(), "Fill light"));
panel.add (new LightButton (lights.getAmbientLight(), "Ambient light"));
setVisible (true);
}
/*
* Set up for keyboard navigation, as usual.
*/
private void addKbdNavig (SimpleUniverse universe, BranchGroup scene) {
KeyNavigatorBehavior kbdBehavior = new KeyNavigatorBehavior (
universe.getViewingPlatform().getViewPlatformTransform());
kbdBehavior.setSchedulingBounds (new BoundingSphere (new Point3d(), Float.MAX_VALUE));
scene.addChild (kbdBehavior);
}
}
File: java3d/Lights/Scene.java
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
import java.awt.Font;
/**
* Create scene graph here.
*/
public class Scene extends BranchGroup {
public Scene () {
// Move to where we want the first object
Transform3D translate = new Transform3D ();
translate.setTranslation (new Vector3d (0.7, 0, -3.));
TransformGroup objTranslate = new TransformGroup(translate);
this.addChild(objTranslate);
// Then we rotate it in X and Y
Transform3D rotate = new Transform3D();
rotate.rotX (Math.toRadians (45.));
Transform3D tempRotate = new Transform3D();
tempRotate.rotY (Math.toRadians (30.));
rotate.mul(tempRotate);
TransformGroup objRotate = new TransformGroup(rotate);
objTranslate.addChild(objRotate);
// Set up its appearance properties, for yellow
Material mat = new Material ();
mat.setDiffuseColor (1.f, 1.f, 0);
mat.setAmbientColor (0.2f, 0.2f, 0);
Appearance appearance = new Appearance();
appearance.setMaterial (mat);
// Add the Box
// We request GENERATE_NORMALS so this object can be lit
objRotate.addChild(new Box (0.1f, 0.3f, 0.1f, Box.GENERATE_NORMALS, appearance));
// A red sphere, in a new location
Transform3D translate2 = new Transform3D();
translate2.setTranslation (new Vector3d (-0.8, 0, -4.));
TransformGroup objTranslate2 = new TransformGroup(translate2);
this.addChild (objTranslate2);
// Set Appearance for red
Material mat2 = new Material ();
mat2.setDiffuseColor (1.f, 0, 0);
mat2.setAmbientColor (0.3f, 0, 0);
Appearance appearance2 = new Appearance();
appearance2.setMaterial (mat2);
// Add the sphere
objTranslate2.addChild (new Sphere (0.3f, Sphere.GENERATE_NORMALS, appearance2));
// A pyramid, in a third location
Transform3D translate3 = new Transform3D();
translate3.setTranslation (new Vector3d (0, 0, -5.));
TransformGroup objTranslate3 = new TransformGroup(translate3);
this.addChild (objTranslate3);
// and rotated in Y
Transform3D rotate3 = new Transform3D();
rotate3.rotY (Math.toRadians (45.));
TransformGroup objRotate3 = new TransformGroup (rotate3);
objTranslate3.addChild (objRotate3);
// Set Appearance for green
Material mat3 = new Material ();
mat3.setDiffuseColor (0, 1.f, 0);
mat3.setAmbientColor (0, 0.3f, 0);
Appearance appearance3 = new Appearance();
appearance3.setMaterial (mat3);
// Add the pyramid, this time make it a separate class
objRotate3.addChild (new Pyramid (appearance3));
// A text label
Transform3D translate4 = new Transform3D();
translate4.setTranslation (new Vector3d (0, 0.5, -3.));
TransformGroup objTranslate4 = new TransformGroup(translate4);
this.addChild (objTranslate4);
// Add the Text2D object
Text2D label = new Text2D ("I am 2D text",
new Color3f (1.f, 1.f, 1.f),
"Helvetica", 24, Font.PLAIN);
objTranslate4.addChild (label);
}
}
File: java3d/Lights/Lights.java
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
/**
* An object to hold our lights, plugs them into given scene,
* also sets up ivars mainLight, fillLight, and ambientLight
*
* Uses typical setup, like portrait or TV studio:
* Main (key) light, directional, from 45 deg. user's right, above
* Fill light, directional, from 45deg. user's left, dimmer
*/
public class Lights {
// So main can get them to send to buttons
private DirectionalLight mainLight;
private DirectionalLight fillLight;
private AmbientLight ambientLight;
public Lights (Scene scene) {
// Main light
mainLight = new DirectionalLight (
new Color3f (1.f, 1.f, 1.f),
new Vector3f (-1.f, -0.5f, -1.f));
mainLight.setInfluencingBounds (new BoundingSphere (new Point3d(), Float.MAX_VALUE));
mainLight.setCapability(Light.ALLOW_STATE_WRITE);
scene.addChild(mainLight);
// Fill light
fillLight = new DirectionalLight (
new Color3f (.5f, .5f, .5f),
new Vector3f (1.f, 0, -1.f));
fillLight.setInfluencingBounds (new BoundingSphere (new Point3d(), Float.MAX_VALUE));
fillLight.setCapability(Light.ALLOW_STATE_WRITE);
scene.addChild(fillLight);
// Ambient
ambientLight = new AmbientLight ();
ambientLight.setInfluencingBounds (new BoundingSphere (new Point3d(), Float.MAX_VALUE));
ambientLight.setCapability(Light.ALLOW_STATE_WRITE);
scene.addChild(ambientLight);
}
public Light getMainLight () {
return mainLight;
}
public Light getFillLight () {
return fillLight;
}
public Light getAmbientLight () {
return ambientLight;
}
}
File: java3d/Lights/LightButton.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.j3d.*;
public class LightButton extends JCheckBox implements ItemListener {
private Light light;
public LightButton (Light light, String label) {
this.light = light;
setText (label);
setSelected (true);
addItemListener (this);
}
/**
* Note no need for repaint()
* canvas updates from scene graph automatically
* whenever scene graph data change
*/
public void itemStateChanged (ItemEvent e) {
light.setEnable (e.getStateChange()==ItemEvent.SELECTED);
}
}