Java/3D/3D Basics
Содержание
Appearance Mixed
/*
* @(#)AppearanceMixed.java 1.23 02/10/21 13:37:08
*
* Copyright (c) 1996-2002 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 javax.media.j3d.Alpha;
import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
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.GraphicsContext3D;
import javax.media.j3d.Group;
import javax.media.j3d.IndexedTriangleArray;
import javax.media.j3d.Material;
import javax.media.j3d.PointAttributes;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Shape3D;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TransparencyAttributes;
import javax.media.j3d.TriangleArray;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.TexCoord2f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class AppearanceMixed extends Applet {
private java.net.URL bgImage;
private java.net.URL texImage;
private SimpleUniverse u = null;
static class MyCanvas3D extends Canvas3D {
private GraphicsContext3D gc;
private static final int vertIndices[] = { 0, 1, 2, 0, 2, 3 };
private static final int normalIndices[] = { 0, 0, 0, 1, 1, 1 };
private IndexedTriangleArray tri = new IndexedTriangleArray(
4,
IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS,
6);
private Point3f vert[] = { new Point3f(-0.12f, -0.12f, 0.0f),
new Point3f(0.12f, -0.12f, 0.0f),
new Point3f(0.12f, 0.12f, 0.0f),
new Point3f(-0.12f, 0.12f, 0.0f), };
private Point3f min[] = { new Point3f(-0.24f, -0.24f, -0.20f),
new Point3f(0.04f, -0.28f, -0.24f),
new Point3f(0.00f, 0.00f, -0.24f),
new Point3f(-0.32f, 0.08f, -0.20f), };
private Point3f max[] = { new Point3f(-0.04f, -0.04f, 0.12f),
new Point3f(0.32f, -0.04f, 0.16f),
new Point3f(0.36f, 0.28f, 0.20f),
new Point3f(-0.04f, 0.24f, 0.16f), };
private Point3f delta[] = { new Point3f(-0.0021f, -0.0017f, 0.0014f),
new Point3f(0.0025f, -0.0013f, -0.0018f),
new Point3f(0.0021f, 0.0017f, 0.0018f),
new Point3f(-0.0025f, 0.0013f, -0.0014f), };
private Vector3f normals[];
private Vector3f v01 = new Vector3f();
private Vector3f v02 = new Vector3f();
private Vector3f v03 = new Vector3f();
public void renderField(int fieldDesc) {
computeVert();
computeNormals();
gc.draw(tri);
}
private void computeVert() {
for (int i = 0; i < 4; i++) {
vert[i].add(delta[i]);
if (vert[i].x > max[i].x) {
vert[i].x = max[i].x;
delta[i].x *= -1.0f;
}
if (vert[i].x < min[i].x) {
vert[i].x = min[i].x;
delta[i].x *= -1.0f;
}
if (vert[i].y > max[i].y) {
vert[i].y = max[i].y;
delta[i].y *= -1.0f;
}
if (vert[i].y < min[i].y) {
vert[i].y = min[i].y;
delta[i].y *= -1.0f;
}
if (vert[i].z > max[i].z) {
vert[i].z = max[i].z;
delta[i].z *= -1.0f;
}
if (vert[i].z < min[i].z) {
vert[i].z = min[i].z;
delta[i].z *= -1.0f;
}
}
tri.setCoordinates(0, vert);
}
private void computeNormals() {
v01.sub(vert[1], vert[0]);
v02.sub(vert[2], vert[0]);
v03.sub(vert[3], vert[0]);
normals[0].cross(v01, v02);
normals[0].normalize();
normals[1].cross(v02, v03);
normals[1].normalize();
tri.setNormals(0, normals);
}
public MyCanvas3D(GraphicsConfiguration gcfg) {
super(gcfg);
// Allocate memory for normals
normals = new Vector3f[2];
normals[0] = new Vector3f();
normals[1] = new Vector3f();
// Set up the indices
tri.setCoordinateIndices(0, vertIndices);
tri.setNormalIndices(0, normalIndices);
// Set up the graphics context
gc = getGraphicsContext3D();
// Create the appearance for the triangle fan
Appearance app = new Appearance();
Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
Color3f objColor = new Color3f(0.0f, 0.0f, 0.8f);
app.setMaterial(new Material(objColor, black, objColor, white,
80.0f));
gc.setAppearance(app);
// Set up the global lights
Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
gc.addLight(new AmbientLight(alColor));
gc.addLight(new DirectionalLight(lColor1, lDir1));
}
}
private BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Create a bounds for the background and lights
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
// Set up the background
TextureLoader bgTexture = new TextureLoader(bgImage, this);
Background bg = new Background(bgTexture.getImage());
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
// Set up the global lights
Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
AmbientLight aLgt = new AmbientLight(alColor);
aLgt.setInfluencingBounds(bounds);
DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
lgt1.setInfluencingBounds(bounds);
objRoot.addChild(aLgt);
objRoot.addChild(lgt1);
// Create a bunch of objects with a behavior and add them
// into the scene graph.
int row, col;
Appearance[][] app = new Appearance[3][3];
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
app[row][col] = createAppearance(row * 3 + col);
for (int i = 0; i < 3; i++) {
double ypos = (double) (i - 1) * 0.6;
for (int j = 0; j < 3; j++) {
double xpos = (double) (j - 1) * 0.6;
objRoot.addChild(createObject(app[i][j], 0.12, xpos, ypos));
}
}
// Let Java 3D perform optimizations on this scene graph.
objRoot.rupile();
return objRoot;
}
private Appearance createAppearance(int idx) {
Appearance app = new Appearance();
// Globally used colors
Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
switch (idx) {
// Unlit solid
case 0: {
// Set up the coloring properties
Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f);
ColoringAttributes ca = new ColoringAttributes();
ca.setColor(objColor);
app.setColoringAttributes(ca);
break;
}
// Unlit wire frame
case 1: {
// Set up the coloring properties
Color3f objColor = new Color3f(0.5f, 0.0f, 0.2f);
ColoringAttributes ca = new ColoringAttributes();
ca.setColor(objColor);
app.setColoringAttributes(ca);
// Set up the polygon attributes
PolygonAttributes pa = new PolygonAttributes();
pa.setPolygonMode(pa.POLYGON_LINE);
pa.setCullFace(pa.CULL_NONE);
app.setPolygonAttributes(pa);
break;
}
// Unlit points
case 2: {
// Set up the coloring properties
Color3f objColor = new Color3f(0.2f, 0.2f, 1.0f);
ColoringAttributes ca = new ColoringAttributes();
ca.setColor(objColor);
app.setColoringAttributes(ca);
// Set up the polygon attributes
PolygonAttributes pa = new PolygonAttributes();
pa.setPolygonMode(pa.POLYGON_POINT);
pa.setCullFace(pa.CULL_NONE);
app.setPolygonAttributes(pa);
// Set up point attributes
PointAttributes pta = new PointAttributes();
pta.setPointSize(5.0f);
app.setPointAttributes(pta);
break;
}
// Lit solid
case 3: {
// Set up the material properties
Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
app.setMaterial(new Material(objColor, black, objColor, white,
80.0f));
break;
}
// Texture mapped, lit solid
case 4: {
// Set up the texture map
TextureLoader tex = new TextureLoader(texImage, this);
app.setTexture(tex.getTexture());
TextureAttributes texAttr = new TextureAttributes();
texAttr.setTextureMode(TextureAttributes.MODULATE);
app.setTextureAttributes(texAttr);
// Set up the material properties
app.setMaterial(new Material(white, black, white, black, 1.0f));
break;
}
// Transparent, lit solid
case 5: {
// Set up the transparency properties
TransparencyAttributes ta = new TransparencyAttributes();
ta.setTransparencyMode(ta.BLENDED);
ta.setTransparency(0.6f);
app.setTransparencyAttributes(ta);
// Set up the polygon attributes
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(pa.CULL_NONE);
app.setPolygonAttributes(pa);
// Set up the material properties
Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f);
app
.setMaterial(new Material(objColor, black, objColor, black,
1.0f));
break;
}
// Lit solid, no specular
case 6: {
// Set up the material properties
Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
app.setMaterial(new Material(objColor, black, objColor, black,
80.0f));
break;
}
// Lit solid, specular only
case 7: {
// Set up the material properties
Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
app.setMaterial(new Material(black, black, black, white, 80.0f));
break;
}
// Another lit solid with a different color
case 8: {
// Set up the material properties
Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f);
app.setMaterial(new Material(objColor, black, objColor, white,
80.0f));
break;
}
default: {
ColoringAttributes ca = new ColoringAttributes();
ca.setColor(new Color3f(0.0f, 1.0f, 0.0f));
app.setColoringAttributes(ca);
}
}
return app;
}
private Group createObject(Appearance app, double scale, double xpos,
double ypos) {
// Create a transform group node to scale and position the object.
Transform3D t = new Transform3D();
t.set(scale, new Vector3d(xpos, ypos, 0.0));
TransformGroup objTrans = new TransformGroup(t);
// Create a second transform group node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at runtime.
TransformGroup spinTg = new TransformGroup();
spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
// Create a simple shape leaf node and set the appearance
Shape3D shape = new Tetrahedron();
shape.setAppearance(app);
// add it to the scene graph.
spinTg.addChild(shape);
// Create a new Behavior object that will perform the desired
// operation on the specified transform object and add it into
// the scene graph.
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
5000, 0, 0, 0, 0, 0);
RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
spinTg, yAxis, 0.0f, (float) Math.PI * 2.0f);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
rotator.setSchedulingBounds(bounds);
// Add the behavior and the transform group to the object
objTrans.addChild(rotator);
objTrans.addChild(spinTg);
return objTrans;
}
public AppearanceMixed() {
}
public AppearanceMixed(java.net.URL bgurl, java.net.URL texurl) {
bgImage = bgurl;
texImage = texurl;
}
public void init() {
if (bgImage == null) {
// the path to the image for an applet
try {
bgImage = new java.net.URL(getCodeBase().toString()
+ "bg.jpg");
} catch (java.net.MalformedURLException ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
}
if (texImage == null) {
// the path to the image for an applet
try {
texImage = new java.net.URL(getCodeBase().toString()
+ "apimage.jpg");
} catch (java.net.MalformedURLException ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
}
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
MyCanvas3D c = new MyCanvas3D(config);
add("Center", c);
// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public void destroy() {
u.cleanup();
}
//
// The following allows AppearanceMixed to be run as an application
// as well as an applet
//
public static void main(String[] args) {
// the path to the image file for an application
java.net.URL bgurl = null;
java.net.URL texurl = null;
try {
bgurl = new java.net.URL("file:bg.jpg");
texurl = new java.net.URL("file:apimage.jpg");
} catch (java.net.MalformedURLException ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
new MainFrame(new AppearanceMixed(bgurl, texurl), 700, 700);
}
}
class Tetrahedron extends Shape3D {
private static final float sqrt3 = (float) Math.sqrt(3.0);
private static final float sqrt3_3 = sqrt3 / 3.0f;
private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
private static final float ycenter = 0.5f * sqrt24_3;
private static final float zcenter = -sqrt3_3;
private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter);
private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter);
private static final Point3f p3 = new Point3f(0.0f, -ycenter, -sqrt3
- zcenter);
private static final Point3f p4 = new Point3f(0.0f, sqrt24_3 - ycenter,
0.0f);
private static final Point3f[] verts = { p1, p2, p4, // front face
p1, p4, p3, // left, back face
p2, p3, p4, // right, back face
p1, p3, p2, // bottom face
};
private TexCoord2f texCoord[] = { new TexCoord2f(0.0f, 0.0f),
new TexCoord2f(1.0f, 0.0f), new TexCoord2f(0.5f, sqrt3 / 2.0f), };
public Tetrahedron() {
int i;
TriangleArray tetra = new TriangleArray(12, TriangleArray.COORDINATES
| TriangleArray.NORMALS | TriangleArray.TEXTURE_COORDINATE_2);
tetra.setCoordinates(0, verts);
for (i = 0; i < 12; i++) {
tetra.setTextureCoordinate(0, i, texCoord[i % 3]);
}
int face;
Vector3f normal = new Vector3f();
Vector3f v1 = new Vector3f();
Vector3f v2 = new Vector3f();
Point3f[] pts = new Point3f[3];
for (i = 0; i < 3; i++)
pts[i] = new Point3f();
for (face = 0; face < 4; face++) {
tetra.getCoordinates(face * 3, pts);
v1.sub(pts[1], pts[0]);
v2.sub(pts[2], pts[0]);
normal.cross(v1, v2);
normal.normalize();
for (i = 0; i < 3; i++) {
tetra.setNormal((face * 3 + i), normal);
}
}
this.setGeometry(tetra);
this.setAppearance(new Appearance());
}
}
Appearance Scope
/*
* @(#)AlternateAppearanceScopeTest.java 1.12 02/10/21 13:34:31
*
* Copyright (c) 1996-2002 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.awt.Container;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.media.j3d.AlternateAppearance;
import javax.media.j3d.AmbientLight;
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.Group;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.BoxLayout;
import javax.swing.JApplet;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
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.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;
public class AlternateAppearanceScopeTest extends JApplet implements
ActionListener {
Material mat1, altMat;
Appearance app, otherApp;
JComboBox altAppMaterialColor;
JComboBox appMaterialColor;
JComboBox altAppScoping;
JComboBox override;
private Group content1 = null;
private Group content2 = null;
BoundingSphere worldBounds;
AlternateAppearance altApp;
Shape3D[] shapes1, shapes2;
boolean shape1Enabled = false, shape2Enabled = false;
// Globally used colors
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
Color3f[] colors = { white, red, green, blue };
private SimpleUniverse u;
public AlternateAppearanceScopeTest() {
}
public void init() {
Container contentPane = getContentPane();
Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
contentPane.add("Center", c);
BranchGroup scene = createSceneGraph();
// SimpleUniverse is a Convenience Utility class
u = new SimpleUniverse(c);
// add mouse behaviors to the viewingPlatform
ViewingPlatform viewingPlatform = u.getViewingPlatform();
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
viewingPlatform.setNominalViewingTransform();
OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
orbit.setSchedulingBounds(bounds);
viewingPlatform.setViewPlatformBehavior(orbit);
u.addBranchGraph(scene);
// Create GUI
JPanel p = new JPanel();
BoxLayout boxlayout = new BoxLayout(p, BoxLayout.Y_AXIS);
p.add(createScopingPanel());
p.add(createMaterialPanel());
p.setLayout(boxlayout);
contentPane.add("South", p);
}
public void destroy() {
u.cleanup();
}
BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
// Create influencing bounds
worldBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), // Center
1000.0); // Extent
Transform3D t = new Transform3D();
// move the object upwards
t.set(new Vector3f(0.0f, 0.1f, 0.0f));
// Shrink the object
t.setScale(0.8);
TransformGroup trans = new TransformGroup(t);
trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
otherApp = new Appearance();
altMat = new Material();
altMat.setCapability(Material.ALLOW_COMPONENT_WRITE);
altMat.setDiffuseColor(new Color3f(0.0f, 1.0f, 0.0f));
otherApp.setMaterial(altMat);
altApp = new AlternateAppearance();
altApp.setAppearance(otherApp);
altApp.setCapability(AlternateAppearance.ALLOW_SCOPE_WRITE);
altApp.setCapability(AlternateAppearance.ALLOW_SCOPE_READ);
altApp.setInfluencingBounds(worldBounds);
objRoot.addChild(altApp);
// Build foreground geometry into two groups. We"ll
// create three directional lights below, one each with
// scope to cover the first geometry group only, the
// second geometry group only, or both geometry groups.
Appearance app1 = new Appearance();
mat1 = new Material();
mat1.setCapability(Material.ALLOW_COMPONENT_WRITE);
mat1.setDiffuseColor(new Color3f(1.0f, 0.0f, 0.0f));
app1.setMaterial(mat1);
content1 = new SphereGroup(0.05f, // radius of spheres
0.4f, // x spacing
0.2f, // y spacing
3, // number of spheres in X
5, // number of spheres in Y
app1, // appearance
true); // alt app override = true
trans.addChild(content1);
shapes1 = ((SphereGroup) content1).getShapes();
content2 = new SphereGroup(0.05f, // radius of spheres
.4f, // x spacing
0.2f, // y spacing
2, // number of spheres in X
5, // number of spheres in Y
app1, // appearance
true); // alt app override = true
trans.addChild(content2);
shapes2 = ((SphereGroup) content2).getShapes();
// Add lights
DirectionalLight light1 = null;
light1 = new DirectionalLight();
light1.setEnable(true);
light1.setColor(new Color3f(0.2f, 0.2f, 0.2f));
light1.setDirection(new Vector3f(1.0f, 0.0f, -1.0f));
light1.setInfluencingBounds(worldBounds);
objRoot.addChild(light1);
DirectionalLight light2 = new DirectionalLight();
light2.setEnable(true);
light2.setColor(new Color3f(0.2f, 0.2f, 0.2f));
light2.setDirection(new Vector3f(-1.0f, 0.0f, 1.0f));
light2.setInfluencingBounds(worldBounds);
objRoot.addChild(light2);
// Add an ambient light to dimly illuminate the rest of
// the shapes in the scene to help illustrate that the
// directional lights are being scoped... otherwise it looks
// like we"re just removing shapes from the scene
AmbientLight ambient = new AmbientLight();
ambient.setEnable(true);
ambient.setColor(new Color3f(1.0f, 1.0f, 1.0f));
ambient.setInfluencingBounds(worldBounds);
objRoot.addChild(ambient);
objRoot.addChild(trans);
return objRoot;
}
JPanel createScopingPanel() {
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder("Scopes"));
String values[] = { "Scoped Set1", "Scoped Set2", "Universal Scope" };
altAppScoping = new JComboBox(values);
altAppScoping.addActionListener(this);
altAppScoping.setSelectedIndex(2);
panel.add(new JLabel("Scoping"));
panel.add(altAppScoping);
String enables[] = { "Enabled Set1", "Enabled Set2", "Enabled set1&2",
"Disabled set1&2" };
override = new JComboBox(enables);
override.addActionListener(this);
override.setSelectedIndex(3);
panel.add(new JLabel("Alternate Appearance Override"));
panel.add(override);
return panel;
}
JPanel createMaterialPanel() {
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder("Appearance Attributes"));
String colorVals[] = { "WHITE", "RED", "GREEN", "BLUE" };
altAppMaterialColor = new JComboBox(colorVals);
altAppMaterialColor.addActionListener(this);
altAppMaterialColor.setSelectedIndex(2);
panel.add(new JLabel("Alternate Appearance MaterialColor"));
panel.add(altAppMaterialColor);
appMaterialColor = new JComboBox(colorVals);
appMaterialColor.addActionListener(this);
appMaterialColor.setSelectedIndex(1);
panel.add(new JLabel("Normal Appearance MaterialColor"));
panel.add(appMaterialColor);
return panel;
}
public void actionPerformed(ActionEvent e) {
Object target = e.getSource();
if (target == altAppMaterialColor) {
altMat.setDiffuseColor(colors[altAppMaterialColor
.getSelectedIndex()]);
} else if (target == altAppScoping) {
for (int i = 0; i < altApp.numScopes(); i++) {
altApp.removeScope(0);
}
if (altAppScoping.getSelectedIndex() == 0) {
altApp.addScope(content1);
} else if (altAppScoping.getSelectedIndex() == 1) {
altApp.addScope(content2);
}
} else if (target == override) {
int i;
if (override.getSelectedIndex() == 0) {
if (!shape1Enabled) {
for (i = 0; i < shapes1.length; i++)
shapes1[i].setAppearanceOverrideEnable(true);
shape1Enabled = true;
}
if (shape2Enabled) {
for (i = 0; i < shapes2.length; i++)
shapes2[i].setAppearanceOverrideEnable(false);
shape2Enabled = false;
}
} else if (override.getSelectedIndex() == 1) {
if (!shape2Enabled) {
for (i = 0; i < shapes2.length; i++)
shapes2[i].setAppearanceOverrideEnable(true);
shape2Enabled = true;
}
if (shape1Enabled) {
for (i = 0; i < shapes1.length; i++)
shapes1[i].setAppearanceOverrideEnable(false);
shape1Enabled = false;
}
} else if (override.getSelectedIndex() == 2) {
if (!shape1Enabled) {
for (i = 0; i < shapes1.length; i++)
shapes1[i].setAppearanceOverrideEnable(true);
shape1Enabled = true;
}
if (!shape2Enabled) {
for (i = 0; i < shapes2.length; i++)
shapes2[i].setAppearanceOverrideEnable(true);
shape2Enabled = true;
}
} else {
if (shape1Enabled) {
for (i = 0; i < shapes1.length; i++)
shapes1[i].setAppearanceOverrideEnable(false);
shape1Enabled = false;
}
if (shape2Enabled) {
for (i = 0; i < shapes2.length; i++)
shapes2[i].setAppearanceOverrideEnable(false);
shape2Enabled = false;
}
}
} else if (target == appMaterialColor) {
mat1.setDiffuseColor(colors[appMaterialColor.getSelectedIndex()]);
}
}
public static void main(String[] args) {
Frame frame = new MainFrame(new AlternateAppearanceScopeTest(), 800,
800);
}
}
/*
* @(#)SphereGroup.java 1.7 02/04/01 15:04:02
*
* Copyright (c) 1996-2002 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.
*/
class SphereGroup extends Group {
Shape3D[] shapes;
int numShapes = 0;
// Constructors
public SphereGroup() {
// radius x,y spacing x,y count appearance
this(0.25f, 0.75f, 0.75f, 5, 5, null, false);
}
public SphereGroup(Appearance app) {
// radius x,y spacing x,y count appearance
this(0.25f, 0.75f, 0.75f, 5, 5, app, false);
}
public SphereGroup(float radius, float xSpacing, float ySpacing,
int xCount, int yCount, boolean overrideflag) {
this(radius, xSpacing, ySpacing, xCount, yCount, null, overrideflag);
}
public SphereGroup(float radius, float xSpacing, float ySpacing,
int xCount, int yCount, Appearance app, boolean overrideflag) {
if (app == null) {
app = new Appearance();
Material material = new Material();
material.setDiffuseColor(new Color3f(0.8f, 0.8f, 0.8f));
material.setSpecularColor(new Color3f(0.0f, 0.0f, 0.0f));
material.setShininess(0.0f);
app.setMaterial(material);
}
double xStart = -xSpacing * (double) (xCount - 1) / 2.0;
double yStart = -ySpacing * (double) (yCount - 1) / 2.0;
Sphere sphere = null;
TransformGroup trans = null;
Transform3D t3d = new Transform3D();
Vector3d vec = new Vector3d();
double x, y = yStart, z = 0.0;
shapes = new Shape3D[xCount * yCount];
for (int i = 0; i < yCount; i++) {
x = xStart;
for (int j = 0; j < xCount; j++) {
vec.set(x, y, z);
t3d.setTranslation(vec);
trans = new TransformGroup(t3d);
addChild(trans);
sphere = new Sphere(radius, // sphere radius
Primitive.GENERATE_NORMALS, // generate normals
16, // 16 divisions radially
app); // it"s appearance
trans.addChild(sphere);
x += xSpacing;
shapes[numShapes] = sphere.getShape();
if (overrideflag)
shapes[numShapes]
.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
numShapes++;
}
y += ySpacing;
}
}
Shape3D[] getShapes() {
return shapes;
}
}
Basic Construct
// JFrame
import javax.swing.JFrame;
// BorderLayout stuff
import java.awt.*;
import javax.swing.*;
// Canvas3D
import javax.media.j3d.Canvas3D;
// The Universe
import com.sun.j3d.utils.universe.SimpleUniverse;
// The BranchGroup
import javax.media.j3d.BranchGroup;
// For the Box
import com.sun.j3d.utils.geometry.Box;
import javax.vecmath.*;
// The directional light
import javax.media.j3d.DirectionalLight;
// For the bouding sphere of the light source
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Appearance;
import javax.media.j3d.Material;
// Transformgroup
import javax.media.j3d.TransformGroup;
import com.sun.j3d.utils.behaviors.mouse.*;
public class BasicConstruct extends JFrame {
/**
* The SimpleUniverse object
*/
protected SimpleUniverse simpleU;
/**
* The root BranchGroup Object.
*/
protected BranchGroup rootBranchGroup;
/**
* Constructor that consturcts the window with the given name.
*
* @param name
* The name of the window, in String format
*/
public BasicConstruct(String name) {
// The next line will construct the window and name it
// with the given name
super(name);
// Perform the initial setup, just once
initial_setup();
}
/**
* Perform the essential setups for the Java3D
*/
protected void initial_setup() {
// A JFrame is a Container -- something that can hold
// other things, e.g a button, a textfield, etc..
// however, for a container to hold something, you need
// to specify the layout of the storage. For our
// example, we would like to use a BorderLayout.
// The next line does just this:
getContentPane().setLayout(new BorderLayout());
// The next step is to setup graphics configuration
// for Java3D. Since different machines/OS have differnt
// configuration for displaying stuff, therefore, for
// java3D to work, it is important to obtain the correct
// graphics configuration first.
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
// Since we are doing stuff via java3D -- meaning we
// cannot write pixels directly to the screen, we need
// to construct a "canvas" for java3D to "paint". And
// this "canvas" will be constructed with the graphics
// information we just obtained.
Canvas3D canvas3D = new Canvas3D(config);
// And we need to add the "canvas to the centre of our
// window..
getContentPane().add("Center", canvas3D);
// Creates the universe
simpleU = new SimpleUniverse(canvas3D);
// First create the BranchGroup object
rootBranchGroup = new BranchGroup();
}
/**
* Adds a light source to the universe
*
* @param direction
* The inverse direction of the light
* @param color
* The color of the light
*/
public void addDirectionalLight(Vector3f direction, Color3f color) {
// Creates a bounding sphere for the lights
BoundingSphere bounds = new BoundingSphere();
bounds.setRadius(1000d);
// Then create a directional light with the given
// direction and color
DirectionalLight lightD = new DirectionalLight(color, direction);
lightD.setInfluencingBounds(bounds);
// Then add it to the root BranchGroup
rootBranchGroup.addChild(lightD);
}
/**
* Adds a box to the universe
*
* @param x
* The x dimension of the box
* @param y
* The y dimension of the box
* @param z
* The z dimension of the box
*/
public void addBox(float x, float y, float z, Color3f diffuse, Color3f spec) {
// Add a box with the given dimension
// First setup an appearance for the box
Appearance app = new Appearance();
Material mat = new Material();
mat.setDiffuseColor(diffuse);
mat.setSpecularColor(spec);
mat.setShininess(5.0f);
app.setMaterial(mat);
Box box = new Box(x, y, z, app);
// Create a TransformGroup and make it the parent of the box
TransformGroup tg = new TransformGroup();
tg.addChild(box);
// Then add it to the rootBranchGroup
rootBranchGroup.addChild(tg);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
MouseRotate myMouseRotate = new MouseRotate();
myMouseRotate.setTransformGroup(tg);
myMouseRotate.setSchedulingBounds(new BoundingSphere());
rootBranchGroup.addChild(myMouseRotate);
MouseTranslate myMouseTranslate = new MouseTranslate();
myMouseTranslate.setTransformGroup(tg);
myMouseTranslate.setSchedulingBounds(new BoundingSphere());
rootBranchGroup.addChild(myMouseTranslate);
MouseZoom myMouseZoom = new MouseZoom();
myMouseZoom.setTransformGroup(tg);
myMouseZoom.setSchedulingBounds(new BoundingSphere());
rootBranchGroup.addChild(myMouseZoom);
}
/**
* Finalise everything to get ready
*/
public void finalise() {
// Then add the branch group into the Universe
simpleU.addBranchGraph(rootBranchGroup);
// And set up the camera position
simpleU.getViewingPlatform().setNominalViewingTransform();
}
public static void main(String[] argv) {
BasicConstruct bc = new BasicConstruct("Foo");
bc.setSize(250, 250);
bc.addBox(0.4f, 0.5f, 0.6f, new Color3f(1, 0, 0), new Color3f(1, 0, 0));
bc.addDirectionalLight(new Vector3f(0f, 0f, -1),
new Color3f(1f, 1f, 0f));
bc.finalise();
bc.show();
return;
}
}
Basic steps needed to display 3D objects
/*
The Joy of Java 3D
by Greg Hopkins
Copyright Copyright 2001
*/
/*
The following program shows you the basic steps needed to display 3D objects.
1. Create a virtual universe to contain your scene.
2. Create a data structure to contain a group of objects.
3. Add an object to the group
4. Position the viewer so that they are looking at the object
5. Add the group of objects to the universe
*/
import javax.media.j3d.BranchGroup;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class Hello3d {
public Hello3d() {
SimpleUniverse universe = new SimpleUniverse();
BranchGroup group = new BranchGroup();
group.addChild(new ColorCube(0.3));
universe.getViewingPlatform().setNominalViewingTransform();
universe.addBranchGraph(group);
}
public static void main(String[] args) {
new Hello3d();
}
} // end of class Hello3d
Getting Started with the Java 3D API written in Java 3D
/*
* YoyoApp.java 1.0 98/11/23
*
* Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* 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.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear facility.
* Licensee represents and warrants that it will not use or redistribute the
* Software for such purposes.
*/
/*
* Getting Started with the Java 3D API written in Java 3D
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import javax.media.j3d.Alpha;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Geometry;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TriangleFanArray;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class YoyoApp extends Applet {
/////////////////////////////////////////////////
//
// create scene graph branch group
//
public class Yoyo extends Shape3D {
////////////////////////////////////////////
//
// create Shape3D with geometry and appearance
// the geometry is created in method yoyoGeometry
// the appearance is created in method yoyoAppearance
//
public Yoyo() {
this.setGeometry(yoyoGeometry());
} // end of Yoyo constructor
////////////////////////////////////////////
//
// create yoyo geometry
// four triangle fans represent the yoyo
// strip indicies_______________
// 0 0N+0 to 1N+0 ( 0 to N )
// 1 1N+1 to 2N+1
// 2 2N+2 to 3N+2
// 3 3N+4 to 4N+3
//
private Geometry yoyoGeometry() {
TriangleFanArray tfa;
int N = 17;
int totalN = 4 * (N + 1);
Point3f coords[] = new Point3f[totalN];
int stripCounts[] = { N + 1, N + 1, N + 1, N + 1 };
float r = 0.6f;
float w = 0.4f;
int n;
double a;
float x, y;
// set the central points for four triangle fan strips
coords[0 * (N + 1)] = new Point3f(0.0f, 0.0f, w);
coords[1 * (N + 1)] = new Point3f(0.0f, 0.0f, 0.0f);
coords[2 * (N + 1)] = new Point3f(0.0f, 0.0f, 0.0f);
coords[3 * (N + 1)] = new Point3f(0.0f, 0.0f, -w);
for (a = 0, n = 0; n < N; a = 2.0 * Math.PI / (N - 1) * ++n) {
x = (float) (r * Math.cos(a));
y = (float) (r * Math.sin(a));
coords[0 * (N + 1) + n + 1] = new Point3f(x, y, w);
coords[1 * (N + 1) + N - n] = new Point3f(x, y, w);
coords[2 * (N + 1) + n + 1] = new Point3f(x, y, -w);
coords[3 * (N + 1) + N - n] = new Point3f(x, y, -w);
}
tfa = new TriangleFanArray(totalN, TriangleFanArray.COORDINATES,
stripCounts);
tfa.setCoordinates(0, coords);
return tfa;
} // end of method yoyoGeometry in class Yoyo
} // end of class Yoyo
/////////////////////////////////////////////////
//
// create scene graph branch group
//
public BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
// Create the transform group node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at runtime. Add it to the
// root of the subgraph.
TransformGroup objSpin = new TransformGroup();
objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(objSpin);
objSpin.addChild(new Yoyo());
// Create a new Behavior object that will perform the desired
// operation on the specified transform object and add it into
// the scene graph.
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, 4000);
RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
objSpin);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
rotator.setSchedulingBounds(bounds);
objSpin.addChild(rotator);
// Let Java 3D perform optimizations on this scene graph.
objRoot.rupile();
return objRoot;
} // end of CreateSceneGraph method of YoyoApp
// Create a simple scene and attach it to the virtual universe
public YoyoApp() {
setLayout(new BorderLayout());
Canvas3D canvas3D = new Canvas3D(null);
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
// SimpleUniverse is a Convenience Utility class
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
} // end of YoyoApp constructor
// The following allows this to be run as an application
// as well as an applet
public static void main(String[] args) {
Frame frame = new MainFrame(new YoyoApp(), 256, 256);
} // end of main method of YoyoApp
} // end of class YoyoApp
HelloJava3Db renders a single, rotated cube
/*
* @(#)HelloJava3Db.java 1.0 98/11/09 15:07:04
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* 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.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
// HelloJava3Db renders a single, rotated cube.
public class HelloJava3Db extends Applet {
public BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// rotate object has composited transformation matrix
Transform3D rotate = new Transform3D();
Transform3D tempRotate = new Transform3D();
rotate.rotX(Math.PI/4.0d);
tempRotate.rotY(Math.PI/5.0d);
rotate.mul(tempRotate);
TransformGroup objRotate = new TransformGroup(rotate);
objRoot.addChild(objRotate);
objRotate.addChild(new ColorCube(0.4));
// Let Java 3D perform optimizations on this scene graph.
objRoot.rupile();
return objRoot;
} // end of CreateSceneGraph method of HelloJava3Db
// Create a simple scene and attach it to the virtual universe
public HelloJava3Db() {
setLayout(new BorderLayout());
Canvas3D canvas3D = new Canvas3D(null);
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
// SimpleUniverse is a Convenience Utility class
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
} // end of HelloJava3Db (constructor)
// The following allows this to be run as an application
// as well as an applet
public static void main(String[] args) {
Frame frame = new MainFrame(new HelloJava3Db(), 256, 256);
} // end of main (method of HelloJava3Db)
} // end of class HelloJava3Db
Positioning the Objects
/*
The Joy of Java 3D
by Greg Hopkins
Copyright Copyright 2001
*/
/*
Positioning the Objects
In Java 3D, locations are described by using x, y, z coordinates. Increasing coordinates
go along the x-axis to the right, along the y-axis upwards, and along the z-axis out of
the screen. This is called a "right-handed" coordinate system because the thumb and first
two fingers of your right hand can be used to represent the three directions. All the
distances are measured in meters.
To place your objects in the scene, you start at point (0,0,0), and then move the objects
wherever you want. Moving the objects is called a "transformation", so the classes you
use are: TransformGroup and Transform3D. You add both the object and the Transform3D to
a TransformGroup before adding the TransformGroup to the rest of your scend
Step Example
1. Create a transform, a transform Transform = new Transform3D();
group and an object transformGroup tg = new TransformGroup();
Cone cone = new Cone(0.5f, 0.5f);
--------------------------------------------------------------------------------------------
2. Specify a location for the object Vector3f vector = new Vector3f(-.2f,.1f , -.4f);
--------------------------------------------------------------------------------------------
3. Set the transform to move (translate) Transform.setTranslation(vector);
the object to that location
--------------------------------------------------------------------------------------------
4. Add the transform to the transform group tg.setTransform(transform);
--------------------------------------------------------------------------------------------
5. Add the object to the transform group tg.addChild(cone);
This example displays the different objects on each axis.
*/
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class Position {
public Position() {
SimpleUniverse universe = new SimpleUniverse();
BranchGroup group = new BranchGroup();
// X axis made of spheres
for (float x = -1.0f; x <= 1.0f; x = x + 0.1f) {
Sphere sphere = new Sphere(0.05f);
TransformGroup tg = new TransformGroup();
Transform3D transform = new Transform3D();
Vector3f vector = new Vector3f(x, .0f, .0f);
transform.setTranslation(vector);
tg.setTransform(transform);
tg.addChild(sphere);
group.addChild(tg);
}
// Y axis made of cones
for (float y = -1.0f; y <= 1.0f; y = y + 0.1f) {
TransformGroup tg = new TransformGroup();
Transform3D transform = new Transform3D();
Cone cone = new Cone(0.05f, 0.1f);
Vector3f vector = new Vector3f(.0f, y, .0f);
transform.setTranslation(vector);
tg.setTransform(transform);
tg.addChild(cone);
group.addChild(tg);
}
// Z axis made of cylinders
for (float z = -1.0f; z <= 1.0f; z = z + 0.1f) {
TransformGroup tg = new TransformGroup();
Transform3D transform = new Transform3D();
Cylinder cylinder = new Cylinder(0.05f, 0.1f);
Vector3f vector = new Vector3f(.0f, .0f, z);
transform.setTranslation(vector);
tg.setTransform(transform);
tg.addChild(cylinder);
group.addChild(tg);
}
Color3f light1Color = new Color3f(.1f, 1.4f, .1f); // green light
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1 = new DirectionalLight(light1Color,
light1Direction);
light1.setInfluencingBounds(bounds);
group.addChild(light1);
universe.getViewingPlatform().setNominalViewingTransform();
// add the group of objects to the Universe
universe.addBranchGraph(group);
}
public static void main(String[] args) {
new Position();
}
}
Simple 3D Demo
import java.awt.BorderLayout;
import java.awt.Frame;
import javax.media.j3d.Alpha;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Point3d;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class HelloWorld {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setSize(640, 480);
frame.setLayout(new BorderLayout());
Canvas3D canvas = new Canvas3D(null);
frame.add("Center", canvas);
SimpleUniverse univ = new SimpleUniverse(canvas);
univ.getViewingPlatform().setNominalViewingTransform();
BranchGroup scene = createSceneGraph();
scene.rupile();
univ.addBranchGraph(scene);
frame.show();
}
private static BranchGroup createSceneGraph() {
// Make a scene graph branch
BranchGroup branch = new BranchGroup();
// Make a changeable 3D transform
TransformGroup trans = new TransformGroup();
trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
branch.addChild(trans);
// Make a shape
ColorCube demo = new ColorCube(0.4);
trans.addChild(demo);
// Make a behavor to spin the shape
Alpha spinAlpha = new Alpha(-1, 4000);
RotationInterpolator spinner = new RotationInterpolator(spinAlpha,
trans);
spinner.setSchedulingBounds(new BoundingSphere(new Point3d(), 1000.0));
trans.addChild(spinner);
return branch;
}
}
Simple Rotation
// From: http://www.micg.et.fh-stralsund.de/Java3D/java3D.htm#Bild1
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import javax.media.j3d.Alpha;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class Rotation extends Applet {
public Rotation() {
}
public void init() {
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
canvas3D = new Canvas3D(config);
add("Center", canvas3D);
BranchGroup szene = macheSzene();
szene.rupile();
universe = new SimpleUniverse(canvas3D);
universe.getViewingPlatform().setNominalViewingTransform();
universe.addBranchGraph(szene);
}
/**
* Erstellt den Szenegraphen
*
* @return BranchGroup
*/
public BranchGroup macheSzene() {
BranchGroup objWurzel = new BranchGroup();
// Transformation, 2 Rotationen:
Transform3D drehung = new Transform3D();
Transform3D drehung2 = new Transform3D();
drehung.rotX(Math.PI / 4.0d);
drehung2.rotY(Math.PI / 5.0d);
drehung.mul(drehung2);
TransformGroup objDreh = new TransformGroup(drehung);
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
spin.addChild(new ColorCube(0.4));
objDreh.addChild(spin);
objWurzel.addChild(objDreh);
// Drehung
Alpha spinAlpha = new Alpha(-1, 5000);
RotationInterpolator dreher = new RotationInterpolator(spinAlpha, spin);
BoundingSphere zone = new BoundingSphere();
dreher.setSchedulingBounds(zone);
spin.addChild(dreher);
return objWurzel;
}
/**
* gibt speicher frei
*/
public void destroy() {
universe.removeAllLocales();
}
public static void main(String[] args) {
frame = new MainFrame(new Rotation(), 500, 500);
frame.setTitle("Rotation");
}
//---- Attribute -----------------------
private SimpleUniverse universe;
private Canvas3D canvas3D;
private static Frame frame;
}