Java tutorial
/* * @(#)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); } }