Java tutorial
/******************************************************************************* * Copyright (c) 1999 Justin Couch * Java Source * * Raw J3D Tutorial * * Version History * Date Version Programmer * ---------- ------- ------------------------------------------ * 01/08/1998 1.0.0 Justin Couch * ******************************************************************************/ // no package // Standard imports import java.awt.Component; import java.awt.Frame; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.net.URL; import javax.media.j3d.Appearance; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.ColoringAttributes; import javax.media.j3d.DirectionalLight; import javax.media.j3d.GeometryArray; import javax.media.j3d.GraphicsConfigTemplate3D; import javax.media.j3d.Group; import javax.media.j3d.ImageComponent; import javax.media.j3d.ImageComponent2D; import javax.media.j3d.IndexedQuadArray; import javax.media.j3d.Light; import javax.media.j3d.Locale; import javax.media.j3d.Material; import javax.media.j3d.Node; import javax.media.j3d.PhysicalBody; import javax.media.j3d.PhysicalEnvironment; import javax.media.j3d.PolygonAttributes; import javax.media.j3d.Shape3D; import javax.media.j3d.Texture; import javax.media.j3d.Texture2D; import javax.media.j3d.TextureAttributes; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.media.j3d.View; import javax.media.j3d.ViewPlatform; import javax.media.j3d.VirtualUniverse; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.vecmath.AxisAngle4f; import javax.vecmath.Color3f; import javax.vecmath.Point3d; import javax.vecmath.Vector3f; // Application specific imports // none /** * Test frame class for the dealing with J3D experimentation that uses Swing * <P> * Basic window consists of a menubar and a J3D window * * @author Justin Couch * @version Who Cares! */ public class J3dSwingFrame extends JFrame implements ActionListener { private JMenuItem close_menu; private Canvas3D canvas; private UniverseManager universe; /** * Construct the test frame with a menubar and 3D canvas */ public J3dSwingFrame() { super("Java3D Tester"); // Disable lightweight menus JPopupMenu.setDefaultLightWeightPopupEnabled(false); JMenuBar menubar = new JMenuBar(); // File menu JMenu file_menu = new JMenu("File"); menubar.add(file_menu); close_menu = new JMenuItem("Exit"); close_menu.addActionListener(this); file_menu.add(close_menu); setJMenuBar(menubar); GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice device = env.getDefaultScreenDevice(); GraphicsConfiguration config = device.getBestConfiguration(template); canvas = new Canvas3D(config); // add the canvas to this frame. Since this is the only thing added to // the main frame we don't care about layout managers etc. getContentPane().add(canvas, "Center"); constructWorld(); setSize(600, 600); } /** * Construct everything that we want in the basic test world */ private void constructWorld() { // create the basic universe universe = new UniverseManager(); /* * // create a light grey coloured background Background bg = new * Background(0.5f, 0.5f, 0.5f); BoundingSphere bounds = new * BoundingSphere(); bounds.setRadius(1000); * bg.setApplicationBounds(bounds); universe.addWorldObject(bg); */ Camera cam = new Camera(); Vector3f loc = new Vector3f(0, 0, 10.0f); cam.setLocation(loc); cam.setHeadLight(true); universe.addCamera(cam); cam.setCanvas(canvas); // add some geometry ExampleGeometry geom = new ExampleGeometry(); universe.addWorldObject(geom); universe.makeLive(); } /** * An mouse action has occurred. Used to process menu item selection. * * @param evt * The event that caused this method to be called. */ public void actionPerformed(ActionEvent evt) { Object src = evt.getSource(); if (src == close_menu) System.exit(0); } /** * Start the application.... */ public static void main(String[] args) { Frame frame = new J3dSwingFrame(); frame.setVisible(true); } } /******************************************************************************* * Copyright (c) 1999 Justin Couch Java Source * * Raw J3D Tutorial * * Version History Date Version Programmer ---------- ------- * ------------------------------------------ 01/08/1998 1.0.0 Justin Couch * ******************************************************************************/ // no package // Application specific imports // none /** * Test class for representing a universe * <P> * Basic universe consisting of a default Locale and three branch graphs for * objects that exist in the display and world spaces, as well as a separate * branch for cameras. * * @author Justin Couch * @version Who Cares! */ class UniverseManager extends VirtualUniverse { private Locale locale; private BranchGroup view_group; private BranchGroup world_object_group; /** * Create the basic universe and all of the supporting infrastructure that * is needed by a J3D application. The default setup just uses a single * local located at the origin. */ public UniverseManager() { locale = new Locale(this); view_group = new BranchGroup(); view_group.setCapability(Group.ALLOW_CHILDREN_EXTEND); world_object_group = new BranchGroup(); world_object_group.setCapability(Group.ALLOW_CHILDREN_EXTEND); } /** * Add a camera to the world. * * @param cam * The camera that may be added */ public void addCamera(Camera cam) { view_group.addChild(cam.getNode()); } /** * Add an object to the world object group. * * @param node * The node that may be added */ public void addWorldObject(Node node) { world_object_group.addChild(node); } /** * Make the universe live by adding the objects to the locale */ public void makeLive() { view_group.compile(); world_object_group.compile(); locale.addBranchGraph(view_group); locale.addBranchGraph(world_object_group); } } /******************************************************************************* * Copyright (c) 1999 Justin Couch Java Source * * Raw J3D Tutorial * * Version History Date Version Programmer ---------- ------- * ------------------------------------------ 01/08/1998 1.0.0 Justin Couch * ******************************************************************************/ // Application specific imports // none /** * Test class for showing the use of a View and ViewPlatform * <P> * Basic view consists of the standard placement. * * @author Justin Couch * @version Who Cares! */ class Camera { private static final double BACK_CLIP_DISTANCE = 100.0; private static final Color3f White = new Color3f(1, 1, 1); private static final BoundingSphere LIGHT_BOUNDS; private Group hud_group; private TransformGroup root_tx_grp; private Transform3D location; private ViewPlatform platform; private View view; private DirectionalLight headlight; private PhysicalBody body; private PhysicalEnvironment env; static { Point3d origin = new Point3d(0, 0, 0); LIGHT_BOUNDS = new BoundingSphere(origin, BACK_CLIP_DISTANCE); } public Camera() { hud_group = new Group(); hud_group.setCapability(Group.ALLOW_CHILDREN_EXTEND); platform = new ViewPlatform(); location = new Transform3D(); root_tx_grp = new TransformGroup(); root_tx_grp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); root_tx_grp.setTransform(location); root_tx_grp.addChild(platform); root_tx_grp.addChild(hud_group); // now create the headlight headlight = new DirectionalLight(); headlight.setCapability(Light.ALLOW_STATE_WRITE); headlight.setColor(White); headlight.setInfluencingBounds(LIGHT_BOUNDS); root_tx_grp.addChild(headlight); body = new PhysicalBody(); env = new PhysicalEnvironment(); view = new View(); view.setBackClipDistance(BACK_CLIP_DISTANCE); view.setPhysicalBody(body); view.setPhysicalEnvironment(env); view.attachViewPlatform(platform); } /** * Set the canvas that this camera is using * * @param canvas * The canvas that is to be used for this camera */ public void setCanvas(Canvas3D canvas) { view.addCanvas3D(canvas); } /** * Set the location of the camera. This is the location of the center of the * camera relative to whatever is used as its root group node. * * @param loc * The location of the camera */ public void setLocation(Vector3f loc) { location.setTranslation(loc); root_tx_grp.setTransform(location); } /** * Set the orientation of the camera. * * @param angle * The orientation of the camera */ public void setOrientation(AxisAngle4f angle) { location.setRotation(angle); root_tx_grp.setTransform(location); } /** * Add some goemetry to the HUD area. This geometry must come complete with * its own parent transform to offset the object by the appropriate amount. * The camera does not do any auto-offsets of geometry. * * @param geom * The geometry to add */ public void addHUDObject(Node geom) { hud_group.addChild(geom); } /** * Enable the headlight that is attached to the camera. * * @param enable * True if the light is to be turned on */ public void setHeadLight(boolean enable) { headlight.setEnable(enable); } /** * Get the J3D node that is used to represent the camera * * @return The root TransformGroup of the camera */ Node getNode() { return root_tx_grp; } } /******************************************************************************* * Copyright (c) 1999 Justin Couch Java Source * * Raw J3D Tutorial * * Version History Date Version Programmer ---------- ------- * ------------------------------------------ 01/08/1998 1.0.0 Justin Couch * ******************************************************************************/ // Application specific imports // none /** * Test class illustrating the use of geometry. * <P> * A simple Shape3D class that contains a flat square constructed from a raw * geometry array. The square is located at the origin with bounds 0.5 along * each axis and lies in the X,Y plain. The normals point along the +Z axis. * However, the geometry is set to do no backface culling so you should see it * regardless of viewing position. * <P> * The basic appearance is set uses color in each corner to blend towards the * others. An emissive color of red is set just in case other colors don't work. * * @author Justin Couch * @version Who Cares! */ class ExampleGeometry extends Shape3D { private IndexedQuadArray geom; private Appearance appearance; private Texture texture; /** * Construct the test object with geometry */ public ExampleGeometry() { constructGeometry(); constructAppearance(); } private void constructGeometry() { int flags = GeometryArray.COORDINATES | GeometryArray.COLOR_4 | GeometryArray.NORMALS; geom = new IndexedQuadArray(4, flags, 4); double[] coordinates = { 0.5, 0.5, 0, 0.5, -0.5, 0, -0.5, -0.5, 0, -0.5, 0.5, 0 }; int[] indices = { 0, 1, 2, 3 }; geom.setCoordinates(0, coordinates); geom.setCoordinateIndices(0, indices); float[] colors = { 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0 }; geom.setColors(0, colors); geom.setColorIndices(0, indices); float[] normal = { 0, 0, 1 }; geom.setNormal(0, normal); geom.setNormal(1, normal); geom.setNormal(2, normal); geom.setNormal(3, normal); setGeometry(geom); } /** * Construct the default appearance. */ private void constructAppearance() { appearance = new Appearance(); TextureAttributes tex_attr = new TextureAttributes(); tex_attr.setTextureMode(TextureAttributes.DECAL); tex_attr.setPerspectiveCorrectionMode(TextureAttributes.FASTEST); appearance.setTextureAttributes(tex_attr); ColoringAttributes col_attr = new ColoringAttributes(); col_attr.setShadeModel(ColoringAttributes.SHADE_GOURAUD); appearance.setColoringAttributes(col_attr); PolygonAttributes rend_attr = new PolygonAttributes(); rend_attr.setCullFace(PolygonAttributes.CULL_NONE); // uncomment this if you want it to display in line draw mode // rend_attr.setPolygonMode(PolygonAttributes.POLYGON_LINE); appearance.setPolygonAttributes(rend_attr); Material mat = new Material(); // Color3f col = new Color3f(1, 0, 0); // mat.setEmissiveColor(col); appearance.setMaterial(mat); setAppearance(appearance); } /** * Set the texture on our goemetry * <P> * Always specified as a URL so that we may fetch it from anywhere. * * @param url * The url to the image. */ public void setTexture(URL url) { Toolkit tk = Toolkit.getDefaultToolkit(); Image src_img = tk.createImage(url); BufferedImage buf_img = null; if (!(src_img instanceof BufferedImage)) { // create a component anonymous inner class to give us the image // observer we need to get the width and height of the source image. Component obs = new Component() { }; int width = src_img.getWidth(obs); int height = src_img.getHeight(obs); // construct the buffered image from the source data. buf_img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics g = buf_img.getGraphics(); g.drawImage(src_img, 0, 0, null); g.dispose(); } else buf_img = (BufferedImage) src_img; src_img.flush(); ImageComponent img_comp = new ImageComponent2D(ImageComponent.FORMAT_RGB, buf_img); texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGB, img_comp.getWidth(), img_comp.getHeight()); appearance.setTexture(texture); buf_img.flush(); } }