/*******************************************************************************
* 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
*
* 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
*
* 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
*
* 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.
*
* 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.
*
* 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
*
* 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();
}
}