java left logo
java middle logo
java right logo
 

Home arrow Other API Tips
 
 
Main Menu
Home
Java Tutorials
Book Reviews
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Sitemap
Java Network
Java Forums
Java Tips Blog




Most Visited Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews
Top Rated Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews


Statistics
Registered Users: 769
Java SE Tips: 614
Java ME Tips: 201
Java EE Tips: 184
Other API Tips: 779
Java Applications: 298
Java Libraries: 209
Java Games: 16
Book Reviews:
 
 
 
How to create an Appearance Explorer in Java3D E-mail
User Rating: / 6
PoorBest 

This Java tip shows how to create an appearance explorer in Java3D.


Image

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsConfiguration;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.text.NumberFormat;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.Vector;

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.Font3D;
import javax.media.j3d.FontExtrusion;
import javax.media.j3d.GeometryArray;
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.LineArray;
import javax.media.j3d.LineAttributes;
import javax.media.j3d.LineStripArray;
import javax.media.j3d.Material;
import javax.media.j3d.PointArray;
import javax.media.j3d.PointAttributes;
import javax.media.j3d.PointLight;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.QuadArray;
import javax.media.j3d.RenderingAttributes;
import javax.media.j3d.Screen3D;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Switch;
import javax.media.j3d.TexCoordGeneration;
import javax.media.j3d.Text3D;
import javax.media.j3d.Texture;
import javax.media.j3d.Texture2D;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransparencyAttributes;
import javax.media.j3d.TriangleArray;
import javax.media.j3d.TriangleFanArray;
import javax.media.j3d.TriangleStripArray;
import javax.media.j3d.View;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Color4f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.TexCoord2f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Triangulator;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class AppearanceExplorer extends JApplet implements
    Java3DExplorerConstants {

  // Scene graph items
  SimpleUniverse u;

  Switch sceneSwitch;

  Group beethoven = null;

  Group galleon = null;

  Switch bgSwitch;

  IntChooser bgChooser;

  Appearance appearance;

  // image grabber
  boolean isApplication;

  Canvas3D canvas;

  OffScreenCanvas3D offScreenCanvas;

  View view;

  // ColoringAttributes
  ColoringAttributes coloringAttr;

  ColoringAttributesEditor coloringAttrEditor;

  Color3f coloringColor;

  int coloringShadeModel = ColoringAttributes.SHADE_GOURAUD;

  // PointAttributes
  PointAttributes pointAttr;

  PointAttributesEditor pointAttrEditor;

  float pointSize = 4.0f;

  boolean pointAAEnable = false;

  // LineAttributes
  LineAttributes lineAttr;

  float lineWidth = 1.0f;

  LineAttributesEditor lineAttrEditor;

  boolean lineAAEnable = false;

  int linePattern = LineAttributes.PATTERN_SOLID;

  // PolygonAttributes
  PolygonAttributes polygonAttr;

  PolygonAttributesEditor polygonAttrEditor;

  int polygonMode = PolygonAttributes.POLYGON_FILL;

  int polygonCull = PolygonAttributes.CULL_NONE;

  float polygonOffsetBias = 1.0f;

  float polygonOffsetFactor = 1.0f;

  // RenderingAttributes
  RenderingAttributes renderAttr;

  RenderingAttributesEditor renderAttrEditor;

  boolean renderVisible = true;

  boolean renderDepthBuffer = true;

  boolean renderDepthBufferWrite = true;

  boolean renderIgnoreVertexColor = false;

  boolean renderRasterOpEnable = false;

  int renderRasterOp = RenderingAttributes.ROP_COPY;

  // TransparencyAttributes
  TransparencyAttributes transpAttr;

  TransparencyAttributesEditor transpAttrEditor;

  int transpMode = TransparencyAttributes.NONE;

  float transpValue = 0.5f;

  // Material
  Material material;

  MaterialEditor materialEditor;

  // Texture2D
  Texture2DEditor texture2DEditor;

  boolean texEnable;

  String texImageFile;

  int texBoundaryModeS;

  int texBoundaryModeT;

  Color4f texBoundaryColor;

  int texMinFilter;

  int texMagFilter;

  int texMipMapMode;

  // TextureAttributes
  TextureAttributes textureAttr;

  TextureAttributesEditor textureAttrEditor;

  int texMode;

  Color4f texBlendColor;

  Transform3D texTransform;

  int texPerspCorrect;

  // TexCoordGeneration
  TexCoordGeneration texGen;

  TexCoordGenerationEditor texGenEditor;

  boolean texGenEnable;

  int texGenMode;

  Vector4f texGenPlaneS;

  Vector4f texGenPlaneT;

  // GUI helpers to allow galleon and beethoven to be loaded as needed
  // to reduce the startup time
  int galleonIndex;

  int beethovenIndex;

  String galleonString = "Obj File: Galleon";

  String beethovenString = "Obj File: Beethoven";

  BranchGroup beethovenPlaceholder;

  BranchGroup galleonPlaceholder;

  // Config items
  Switch lightSwitch;

  String snapImageString = "Snap Image";

  String outFileBase = "appear";

  int outFileSeq = 0;

  float offScreenScale = 1.5f;

  // Temporaries that are reused
  Transform3D tmpTrans = new Transform3D();

  Vector3f tmpVector = new Vector3f();

  AxisAngle4f tmpAxisAngle = new AxisAngle4f();

  // geometric constant
  Point3f origin = new Point3f();

  Vector3f yAxis = new Vector3f(0.0f1.0f0.0f);

  // NumberFormat to print out floats with only two digits
  NumberFormat nf;

  // Base for URLs, used to handle application/applet split
  String codeBaseString = null;

  // create the appearance and it's components
  void setupAppearance() {
    appearance = new Appearance();

    // ColoringAttributes
    coloringColor = new Color3f(red);
    coloringAttr = new ColoringAttributes(coloringColor, coloringShadeModel);
    coloringAttr.setCapability(ColoringAttributes.ALLOW_COLOR_WRITE);
    coloringAttr.setCapability(ColoringAttributes.ALLOW_SHADE_MODEL_WRITE);
    appearance.setColoringAttributes(coloringAttr);

    // set up the editor
    coloringAttrEditor = new ColoringAttributesEditor(coloringAttr);

    // PointAttributes
    pointAttr = new PointAttributes(pointSize, pointAAEnable);
    pointAttr.setCapability(PointAttributes.ALLOW_SIZE_WRITE);
    pointAttr.setCapability(PointAttributes.ALLOW_ANTIALIASING_WRITE);
    appearance.setPointAttributes(pointAttr);

    // set up the editor
    pointAttrEditor = new PointAttributesEditor(pointAttr);

    // LineAttributes
    lineAttr = new LineAttributes(lineWidth, linePattern, lineAAEnable);
    lineAttr.setCapability(LineAttributes.ALLOW_WIDTH_WRITE);
    lineAttr.setCapability(LineAttributes.ALLOW_PATTERN_WRITE);
    lineAttr.setCapability(LineAttributes.ALLOW_ANTIALIASING_WRITE);
    appearance.setLineAttributes(lineAttr);

    // set up the editor
    lineAttrEditor = new LineAttributesEditor(lineAttr);

    // PolygonAttributes
    polygonAttr = new PolygonAttributes(polygonMode, polygonCull, 0.0f);
    polygonAttr.setPolygonOffset(polygonOffsetBias);
    polygonAttr.setPolygonOffsetFactor(polygonOffsetFactor);
    polygonAttr.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
    polygonAttr.setCapability(PolygonAttributes.ALLOW_CULL_FACE_WRITE);
    polygonAttr.setCapability(PolygonAttributes.ALLOW_OFFSET_WRITE);
    appearance.setPolygonAttributes(polygonAttr);

    // set up the editor
    polygonAttrEditor = new PolygonAttributesEditor(polygonAttr);

    // Rendering attributes
    renderAttr = new RenderingAttributes(renderDepthBuffer,
        renderDepthBufferWrite, 0.0f, RenderingAttributes.ALWAYS,
        renderVisible, renderIgnoreVertexColor, renderRasterOpEnable,
        renderRasterOp);
    renderAttr
        .setCapability(RenderingAttributes.ALLOW_IGNORE_VERTEX_COLORS_WRITE);
    renderAttr.setCapability(RenderingAttributes.ALLOW_VISIBLE_WRITE);
    renderAttr.setCapability(RenderingAttributes.ALLOW_RASTER_OP_WRITE);
    renderAttr
        .setCapability(RenderingAttributes.ALLOW_ALPHA_TEST_FUNCTION_WRITE);
    renderAttr
        .setCapability(RenderingAttributes.ALLOW_ALPHA_TEST_VALUE_WRITE);
    appearance.setRenderingAttributes(renderAttr);
    appearance.setCapability(Appearance.ALLOW_RENDERING_ATTRIBUTES_WRITE);

    // set up the editor
    renderAttrEditor = new RenderingAttributesEditor(renderAttr);

    // TransparencyAttributes
    transpAttr = new TransparencyAttributes(transpMode, transpValue);
    transpAttr.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
    transpAttr.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
    transpAttr
        .setCapability(TransparencyAttributes.ALLOW_BLEND_FUNCTION_WRITE);
    appearance.setTransparencyAttributes(transpAttr);

    // set up the editor
    transpAttrEditor = new TransparencyAttributesEditor(transpAttr);

    // Material
    material = new Material(red, black, red, white, 20.f);
    material.setLightingEnable(false);
    material.setCapability(Material.ALLOW_COMPONENT_WRITE);
    appearance.setMaterial(material);

    // material presets
    String[] materialNames = "Red""White""Red Ambient",
        "Red Diffuse""Grey Emissive""White Specular""Aluminium",
        "Blue Plastic""Copper""Gold""Red Alloy""Black Onyx" };
    Material[] materialPresets = new Material[materialNames.length];
    materialPresets[0new Material(red, black, red, white, 20.0f);
    materialPresets[1new Material(white, black, white, white, 20.0f);
    materialPresets[2new Material(red, black, black, black, 20.0f);
    materialPresets[3new Material(black, black, red, black, 20.0f);
    materialPresets[4new Material(black, grey, black, black, 20.0f);
    materialPresets[5new Material(black, black, black, white, 20.0f);
    Color3f alum = new Color3f(0.37f0.37f0.37f);
    Color3f alumSpec = new Color3f(0.89f0.89f0.89f);
    materialPresets[6new Material(alum, black, alum, alumSpec, 17);
    Color3f bluePlastic = new Color3f(0.20f0.20f0.70f);
    Color3f bluePlasticSpec = new Color3f(0.85f0.85f0.85f);
    materialPresets[7new Material(bluePlastic, black, bluePlastic,
        bluePlasticSpec, 22);
    Color3f copper = new Color3f(0.30f0.10f0.00f);
    ;
    Color3f copperSpec = new Color3f(0.75f0.30f0.00f);
    materialPresets[8new Material(copper, black, copper, copperSpec, 10);
    Color3f gold = new Color3f(0.49f0.34f0.00f);
    Color3f goldSpec = new Color3f(0.89f0.79f0.00f);
    materialPresets[9new Material(gold, black, gold, goldSpec, 15);
    Color3f redAlloy = new Color3f(0.34f0.00f0.34f);
    Color3f redAlloySpec = new Color3f(0.84f0.00f0.00f);
    materialPresets[10new Material(redAlloy, black, redAlloy,
        redAlloySpec, 15);
    Color3f blackOnyxSpec = new Color3f(0.72f0.72f0.72f);
    materialPresets[11new Material(black, black, black, blackOnyxSpec,
        23);

    // set up the editor
    materialEditor = new MaterialPresetEditor(material, materialNames,
        materialPresets);

    // Texture2D

    // set the values to the defaults
    texEnable = false;
    texMipMapMode = Texture.BASE_LEVEL;
    texBoundaryModeS = Texture.WRAP;
    texBoundaryModeT = Texture.WRAP;
    texMinFilter = Texture.BASE_LEVEL_POINT;
    texMagFilter = Texture.BASE_LEVEL_POINT;
    texBoundaryColor = new Color4f(0.0f0.0f0.0f0.0f);

    // set up the image choices
    String[] texImageNames = "Earth""Fish"};
    String[] texImageFileNames = "earth.jpg""fish1.gif"};
    int texImageFileIndex = 0;

    // set up the appearance to allow the texture to be changed
    appearance.setCapability(Appearance.ALLOW_TEXTURE_WRITE);

    // set up the editor (this will create the initial Texture2D and
    // assign it to the appearance)
    texture2DEditor = new Texture2DEditor(appearance, codeBaseString,
        texImageNames, texImageFileNames, texImageFileIndex, texEnable,
        texBoundaryModeS, texBoundaryModeT, texMinFilter, texMagFilter,
        texMipMapMode, texBoundaryColor);

    // TextureAttributes
    texMode = TextureAttributes.REPLACE;
    texBlendColor = new Color4f(1.0f1.0f1.0f1.0f);
    texTransform = new Transform3D();
    texPerspCorrect = TextureAttributes.NICEST;
    textureAttr = new TextureAttributes(texMode, texTransform,
        texBlendColor, texPerspCorrect);

    // set the capabilities to allow run time changes
    textureAttr.setCapability(TextureAttributes.ALLOW_MODE_WRITE);
    textureAttr.setCapability(TextureAttributes.ALLOW_BLEND_COLOR_WRITE);
    textureAttr.setCapability(TextureAttributes.ALLOW_TRANSFORM_WRITE);

    // connect it to the appearance
    appearance.setTextureAttributes(textureAttr);

    // setup the editor
    textureAttrEditor = new TextureAttributesEditor(textureAttr);

    // set up the tex coordinate generation
    texGenEnable = false;
    texGenMode = TexCoordGeneration.OBJECT_LINEAR;
    texGenPlaneS = new Vector4f(1.0f0.0f0.0f0.0f);
    texGenPlaneT = new Vector4f(0.0f1.0f0.0f0.0f);

    // set the appearance so that we can replace the tex gen when live
    appearance.setCapability(Appearance.ALLOW_TEXGEN_WRITE);

    // setup the editor
    texGenEditor = new TexCoordGenerationEditor(appearance, texGenEnable,
        texGenMode, texGenPlaneS, texGenPlaneT);

  }

  int powerOfTwo(int value) {
    int retval = 2;
    while (retval < value) {
      retval *= 2;
    }
    return retval;
  }

  // Point Array with three points
  Shape3D createPointArray() {

    Point3f pnt[] new Point3f[3];
    pnt[0new Point3f(-1.0f, -1.0f0.0f);
    pnt[1new Point3f(1.0f, -1.0f0.0f);
    pnt[2new Point3f(1.0f1.0f0.0f);

    PointArray pa = new PointArray(3, GeometryArray.COORDINATES);
    pa.setCoordinates(0, pnt);

    return new Shape3D(pa, appearance);
  }

  // Line Array with two lines with vertex colors
  Shape3D createLineArray() {

    Point3f pnt[] new Point3f[4];
    pnt[0new Point3f(-1.0f, -1.0f0.0f);
    pnt[1new Point3f(1.0f, -1.0f0.0f);
    pnt[2new Point3f(1.0f1.0f0.0f);
    pnt[3new Point3f(-1.0f1.0f0.0f);
    Color3f colrs[] new Color3f[4];
    colrs[0= black;
    colrs[1= white;
    colrs[2= red;
    colrs[3= green;

    LineArray la = new LineArray(4, GeometryArray.COORDINATES
        | GeometryArray.COLOR_3);
    la.setCoordinates(0, pnt);
    la.setColors(0, colrs);

    return new Shape3D(la, appearance);
  }

  // Triangle Array with one triangle with vertex colors and a facet normal
  Shape3D createTriangleArray() {

    Point3f pnt[] new Point3f[3];
    pnt[0new Point3f(-1.0f, -1.0f0.0f);
    pnt[1new Point3f(1.0f, -1.0f0.0f);
    pnt[2new Point3f(1.0f1.0f0.0f);
    Color3f colrs[] new Color3f[3];
    colrs[0= red;
    colrs[1= green;
    colrs[2= blue;
    Vector3f norms[] new Vector3f[3];
    Vector3f triNormal = new Vector3f(0.0f0.0f1.0f);
    norms[0= triNormal;
    norms[1= triNormal;
    norms[2= triNormal;

    TriangleArray ta = new TriangleArray(3, GeometryArray.COORDINATES
        | GeometryArray.COLOR_3 | GeometryArray.NORMALS);
    ta.setCoordinates(0, pnt);
    ta.setColors(0, colrs);
    ta.setNormals(0, norms);

    return new Shape3D(ta, appearance);
  }

  // Line Strip Array with two lines with 3 and 2 vertices each making
  // a two segment line and a one segment line
  Shape3D createLineStripArray() {

    int[] stripLengths = new int[2];
    stripLengths[03;
    stripLengths[12;
    Point3f pnt[] new Point3f[5];
    // first line
    pnt[0new Point3f(-1.0f, -1.0f0.0f);
    pnt[1new Point3f(1.0f, -1.0f0.0f);
    pnt[2new Point3f(1.0f1.0f0.0f);
    // second line
    pnt[3new Point3f(0.5f0.5f0.0f);
    pnt[4new Point3f(-0.5f, -0.5f0.0f);

    LineStripArray lsa = new LineStripArray(5, GeometryArray.COORDINATES,
        stripLengths);
    lsa.setCoordinates(0, pnt);

    return new Shape3D(lsa, appearance);
  }

  Shape3D createTriangleStripArray() {

    int[] stripLengths = new int[1];
    stripLengths[05;
    Point3f pnt[] new Point3f[5];
    pnt[0new Point3f(-1.0f, -1.0f0.0f);
    pnt[1new Point3f(1.0f, -1.0f0.0f);
    pnt[2new Point3f(-1.0f0.0f0.0f);
    pnt[3new Point3f(1.0f0.0f0.0f);
    pnt[4new Point3f(1.0f1.0f0.0f);

    TriangleStripArray tsa = new TriangleStripArray(5,
        GeometryArray.COORDINATES, stripLengths);
    tsa.setCoordinates(0, pnt);

    return new Shape3D(tsa, appearance);
  }

  Shape3D createTriangleFanArray() {

    int[] stripLengths = new int[1];
    stripLengths[05;
    Point3f pnt[] new Point3f[5];
    pnt[0new Point3f(-1.0f, -1.0f0.0f);
    pnt[1new Point3f(1.0f, -1.0f0.0f);
    pnt[2new Point3f(1.0f0.0f0.0f);
    pnt[3new Point3f(0.0f1.0f0.0f);
    pnt[4new Point3f(-1.0f1.0f0.0f);

    TriangleFanArray tfa = new TriangleFanArray(5,
        GeometryArray.COORDINATES, stripLengths);
    tfa.setCoordinates(0, pnt);

    return new Shape3D(tfa, appearance);
  }

  Shape3D createTexTris() {

    Point3f pnt[] new Point3f[9];
    pnt[0new Point3f(-0.8f, -0.8f0.0f);
    pnt[1new Point3f(-0.5f, -0.7f0.0f);
    pnt[2new Point3f(-0.7f0.7f0.0f);

    pnt[3new Point3f(-0.4f0.7f0.0f);
    pnt[4new Point3f(0.0f, -0.7f0.0f);
    pnt[5new Point3f(0.4f0.7f0.0f);

    pnt[6new Point3f(0.5f0.7f0.0f);
    pnt[7new Point3f(0.5f, -0.7f0.0f);
    pnt[8new Point3f(0.9f0.0f0.0f);

    TexCoord2f texCoord[] new TexCoord2f[9];
    texCoord[0new TexCoord2f(0.05f0.90f);
    texCoord[1new TexCoord2f(0.25f0.10f);
    texCoord[2