/*
* @(#)Pyramid2Cube.java 1.18 02/10/21 13:45:50
*
* 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 java.util.Enumeration;
import javax.media.j3d.Alpha;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.Morph;
import javax.media.j3d.QuadArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.SimpleUniverse;
public class Pyramid2Cube extends Applet {
private SimpleUniverse u = null;
private BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Create a Transformgroup to scale all objects so they
// appear in the scene.
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.4);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
// Create a bounds for the background and behavior
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
// Set up the background
Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objScale.addChild(bg);
//
// Create the transform group nodes for the 3 original objects
// and the morphed object. Add them to the root of the
// branch graph.
//
TransformGroup objTrans[] = new TransformGroup[4];
for (int i = 0; i < 4; i++) {
objTrans[i] = new TransformGroup();
objScale.addChild(objTrans[i]);
}
Transform3D tr = new Transform3D();
Transform3D rotY15 = new Transform3D();
rotY15.rotY(15.0 * Math.PI / 180.0);
objTrans[0].getTransform(tr);
tr.setTranslation(new Vector3d(-3.0, 1.5, -6.5));
tr.mul(rotY15);
objTrans[0].setTransform(tr);
objTrans[1].getTransform(tr);
tr.setTranslation(new Vector3d(0.0, 1.5, -6.5));
tr.mul(rotY15);
objTrans[1].setTransform(tr);
objTrans[2].getTransform(tr);
tr.setTranslation(new Vector3d(3.0, 1.5, -6.5));
tr.mul(rotY15);
objTrans[2].setTransform(tr);
objTrans[3].getTransform(tr);
tr.setTranslation(new Vector3d(0.0, -2.0, -5.0));
tr.mul(rotY15);
objTrans[3].setTransform(tr);
// Now create simple geometries.
QuadArray g[] = new QuadArray[3];
Shape3D shape[] = new Shape3D[3];
for (int i = 0; i < 3; i++) {
g[i] = null;
shape[i] = null;
}
g[0] = new ColorPyramidUp();
g[1] = new ColorCube();
g[2] = new ColorPyramidDown();
Appearance a = new Appearance();
for (int i = 0; i < 3; i++) {
shape[i] = new Shape3D(g[i], a);
objTrans[i].addChild(shape[i]);
}
//
// Create a Morph node, and set the appearance and input geometry
// arrays. Set the Morph node's capability bits to allow the weights
// to be modified at runtime.
//
Morph morph = new Morph((GeometryArray[]) g, a);
morph.setCapability(Morph.ALLOW_WEIGHTS_READ);
morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
objTrans[3].addChild(morph);
// Now create the Alpha object that controls the speed of the
// morphing operation.
Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE
| Alpha.DECREASING_ENABLE, 0, 0, 4000, 1000, 500, 4000, 1000,
500);
// Finally, create the morphing behavior
MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph);
mBeh.setSchedulingBounds(bounds);
objScale.addChild(mBeh);
return objRoot;
}
public Pyramid2Cube() {
}
public void init() {
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);
// 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();
}
public static void main(String[] args) {
new MainFrame(new Pyramid2Cube(), 700, 700);
}
}
class ColorPyramidUp extends QuadArray {
private static final float[] verts = {
// front face
1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f,
-1.0f, 1.0f,
// back face
-1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f,
// right face
1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f,
// left face
-1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f,
-1.0f, -1.0f,
// top face
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f,
// bottom face
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, };
private static final float[] colors = {
// front face (cyan)
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f,
// back face (magenta)
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f,
// right face (yellow)
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f,
// left face (blue)
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f,
// top face (green)
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f,
// bottom face (red)
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f,
};
ColorPyramidUp() {
super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
setCoordinates(0, verts);
setColors(0, colors);
}
}
class ColorCube extends QuadArray {
private static final float[] verts = {
// front face
1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
-1.0f, 1.0f,
// back face
-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f,
// right face
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,
// left face
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
-1.0f, -1.0f,
// top face
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, 1.0f,
// bottom face
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, };
private static final float[] colors = {
// front face (red)
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f,
// back face (green)
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f,
// right face (blue)
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f,
// left face (yellow)
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f,
// top face (magenta)
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f,
// bottom face (cyan)
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, };
ColorCube() {
super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
setCoordinates(0, verts);
setColors(0, colors);
}
}
class ColorPyramidDown extends QuadArray {
private static final float[] verts = {
// front face
0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, 0.0f,
// back face
0.0f, -1.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 0.0f,
-1.0f, 0.0f,
// right face
0.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, 0.0f,
// left face
0.0f, -1.0f, 0.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 0.0f,
-1.0f, 0.0f,
// top face
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, 1.0f,
// bottom face
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, };
private static final float[] colors = {
// front face (green)
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f,
// back face (red)
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f,
// right face (yellow)
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f,
// left face (magenta)
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f,
// top face (blue)
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f,
// bottom face (cyan)
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, };
ColorPyramidDown() {
super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
setCoordinates(0, verts);
setColors(0, colors);
}
}
//User-defined morphing behavior class
class MorphingBehavior extends Behavior {
Alpha alpha;
Morph morph;
double weights[];
WakeupOnElapsedFrames w = new WakeupOnElapsedFrames(0);
// Override Behavior's initialize method to setup wakeup criteria
public void initialize() {
alpha.setStartTime(System.currentTimeMillis());
// Establish initial wakeup criteria
wakeupOn(w);
}
// Override Behavior's stimulus method to handle the event
public void processStimulus(Enumeration criteria) {
// NOTE: This assumes 3 objects. It should be generalized to
// "n" objects.
double val = alpha.value();
if (val < 0.5) {
double a = val * 2.0;
weights[0] = 1.0 - a;
weights[1] = a;
weights[2] = 0.0;
} else {
double a = (val - 0.5) * 2.0;
weights[0] = 0.0;
weights[1] = 1.0f - a;
weights[2] = a;
}
morph.setWeights(weights);
// Set wakeup criteria for next time
wakeupOn(w);
}
public MorphingBehavior(Alpha a, Morph m) {
alpha = a;
morph = m;
weights = morph.getWeights();
}
}
|