/*
* @(#)LightBug.java 1.2 01/08/01 11:02:18
*
* ************************************************************** "Copyright (c)
* 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed,licensed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility."
*
* ***************************************************************************
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Link;
import javax.media.j3d.Material;
import javax.media.j3d.PointLight;
import javax.media.j3d.SharedGroup;
import javax.media.j3d.SpotLight;
import javax.media.j3d.Switch;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;
public class LightBug extends Applet implements ActionListener {
// Scene graph items
SimpleUniverse u;
Switch spheresSwitch;
Switch lightSwitch;
// Light items
DirectionalLight lightDirectional;
PointLight lightPoint;
SpotLight lightSpot;
String lightNoneString = "None";
String lightDirectionalString = "Directional";
String lightPointString = "Point";
String lightSpotString = "Spot";
JRadioButton lightNoneButton;
JRadioButton lightDirectionalButton;
JRadioButton lightPointButton;
JRadioButton lightSpotButton;
static final int LIGHT_NONE = Switch.CHILD_NONE;
static final int LIGHT_DIRECTIONAL = 0;
static final int LIGHT_POINT = 1;
static final int LIGHT_SPOT = 2;
// Temporaries that are reused
Transform3D tmpTrans = new Transform3D();
Vector3f tmpVector = new Vector3f();
AxisAngle4f tmpAxisAngle = new AxisAngle4f();
// colors
Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
Color3f grey = new Color3f(0.1f, 0.1f, 0.1f);
Color3f skyBlue = new Color3f(0.6f, 0.7f, 0.9f);
// geometric constant
Point3f origin = new Point3f();
Vector3f yAxis = new Vector3f(0.0f, 1.0f, 0.0f);
// NumberFormat to print out floats with only two digits
NumberFormat nf;
// sets up a grid of spheres
void setupSpheres() {
// create a Switch for the spheres, allow switch changes
spheresSwitch = new Switch(Switch.CHILD_ALL);
spheresSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
// Set up an appearance to make the Sphere with red ambient,
// black emmissive, red diffuse and white specular coloring
Material material = new Material(red, black, red, white, 64);
Appearance appearance = new Appearance();
appearance.setMaterial(material);
// create a sphere and put it into a shared group
Sphere sphere = new Sphere(0.5f, appearance);
SharedGroup sphereSG = new SharedGroup();
sphereSG.addChild(sphere);
// create a grid of spheres in the z=0 plane
// each has a TransformGroup to position the sphere which contains
// a link to the shared group for the sphere
for (int y = -2; y <= 2; y++) {
for (int x = -2; x <= 2; x++) {
TransformGroup tg = new TransformGroup();
tmpVector.set(x * 1.2f, y * 1.2f, 0.0f);
tmpTrans.set(tmpVector);
tg.setTransform(tmpTrans);
tg.addChild(new Link(sphereSG));
spheresSwitch.addChild(tg);
}
}
}
/*
* Set up the lights. This is a group which contains the ambient light and a
* switch for the other lights. LIGHT_DIRECTIONAL : white light pointing
* along Z axis LIGHT_POINT : white light near upper left corner of spheres
* LIGHT_SPOT : white light near upper left corner of spheres, pointing
* towards center.
*/
void setupLights() {
// set up the BoundingSphere for all the lights
BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
// create the switch and set the default
lightSwitch = new Switch();
lightSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
lightSwitch.setWhichChild(LIGHT_DIRECTIONAL);
// Set up the directional light
Vector3f lightDirection = new Vector3f(0.0f, 0.0f, -1.0f);
lightDirectional = new DirectionalLight(white, lightDirection);
lightDirectional.setInfluencingBounds(bounds);
lightSwitch.addChild(lightDirectional);
// Set up the point light
Point3f lightPosition = new Point3f(-1.0f, 1.0f, 0.6f);
Point3f lightAttenuation = new Point3f(0.0f, 1.0f, 0.0f);
lightPoint = new PointLight(white, lightPosition, lightAttenuation);
lightPoint.setInfluencingBounds(bounds);
lightSwitch.addChild(lightPoint);
// Set up the spot light
// Point the light back at the origin
Vector3f lightSpotDirection = new Vector3f(lightPosition);
lightSpotDirection.negate(); // point back
lightSpotDirection.normalize(); // make unit length
float spreadAngle = 60; // degrees
float concentration = 5.0f;
lightSpot = new SpotLight(white, lightPosition, lightAttenuation,
lightSpotDirection, (float) Math.toRadians(spreadAngle),
concentration);
lightSpot.setInfluencingBounds(bounds);
lightSwitch.addChild(lightSpot);
}
public void actionPerformed(ActionEvent e) {
String action = e.getActionCommand();
Object source = e.getSource();
if (action == lightNoneString) {
System.out.println("light_none");
lightSwitch.setWhichChild(LIGHT_NONE);
} else if (action == lightDirectionalString) {
System.out.println("light_directional");
lightSwitch.setWhichChild(LIGHT_DIRECTIONAL);
} else if (action == lightPointString) {
System.out.println("light_point");
lightSwitch.setWhichChild(LIGHT_POINT);
} else if (action == lightSpotString) {
System.out.println("light_spot");
lightSwitch.setWhichChild(LIGHT_SPOT);
}
}
BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Add the primitives to the scene
setupSpheres();
objRoot.addChild(spheresSwitch);
setupLights();
objRoot.addChild(lightSwitch);
return objRoot;
}
public LightBug() {
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
// Get the viewing platform
ViewingPlatform viewingPlatform = u.getViewingPlatform();
// Move the viewing platform back to enclose the -4 -> 4 range
double viewRadius = 4.0; // want to be able to see circle
// of viewRadius size around origin
// get the field of view
double fov = u.getViewer().getView().getFieldOfView();
// calc view distance to make circle view in fov
float viewDistance = (float) (viewRadius / Math.tan(fov / 2.0));
tmpVector.set(0.0f, 0.0f, viewDistance);// setup offset
tmpTrans.set(tmpVector); // set trans to translate
// move the view platform
viewingPlatform.getViewPlatformTransform().setTransform(tmpTrans);
// add an orbit behavior to move the viewing platform
OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.STOP_ZOOM);
orbit.setMinRadius(0.5);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
orbit.setSchedulingBounds(bounds);
viewingPlatform.setViewPlatformBehavior(orbit);
u.addBranchGraph(scene);
add("South", lightPanel());
}
JPanel lightPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 1));
panel.add(new JLabel("Light type"));
// create the buttons
JRadioButton lightNoneButton = new JRadioButton(lightNoneString);
JRadioButton lightDirectionalButton = new JRadioButton(
lightDirectionalString);
JRadioButton lightPointButton = new JRadioButton(lightPointString);
JRadioButton lightSpotButton = new JRadioButton(lightSpotString);
// set up the action commands
lightNoneButton.setActionCommand(lightNoneString);
lightDirectionalButton.setActionCommand(lightDirectionalString);
lightPointButton.setActionCommand(lightPointString);
lightSpotButton.setActionCommand(lightSpotString);
// add the buttons to a group so that only one can be selected
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(lightNoneButton);
buttonGroup.add(lightDirectionalButton);
buttonGroup.add(lightPointButton);
buttonGroup.add(lightSpotButton);
// register the applet as the listener for the buttons
lightNoneButton.addActionListener(this);
lightDirectionalButton.addActionListener(this);
lightPointButton.addActionListener(this);
lightSpotButton.addActionListener(this);
// add the buttons to the panel
panel.add(lightNoneButton);
panel.add(lightDirectionalButton);
panel.add(lightPointButton);
panel.add(lightSpotButton);
// set the default
lightDirectionalButton.setSelected(true);
return panel;
}
public void destroy() {
u.removeAllLocales();
}
// The following allows LightBug to be run as an application
// as well as an applet
//
public static void main(String[] args) {
new MainFrame(new LightBug(), 600, 800);
}
}
|