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 use colored backgrounds in Java3D E-mail
User Rating: / 1
PoorBest 

This Java tip illustrates the use of colored backgrounds in Java 3D scenes.


Image

import java.applet.Applet;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.CheckboxMenuItem;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.util.Enumeration;
import java.util.EventListener;

import javax.media.j3d.AmbientLight;
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.DirectionalLight;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.Group;
import javax.media.j3d.IndexedQuadArray;
import javax.media.j3d.IndexedTriangleStripArray;
import javax.media.j3d.Light;
import javax.media.j3d.Link;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.media.j3d.SharedGroup;
import javax.media.j3d.Texture;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.PlatformGeometry;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.Viewer;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class ExBackgroundColor extends Java3DFrame {
  //--------------------------------------------------------------
  //  SCENE CONTENT
  //--------------------------------------------------------------

  //
  //  Nodes (updated via menu)
  //
  private Background background = null;

  //
  //  Build scene
  //
  public Group buildScene() {
    // Get the current color
    Color3f color = (Color3fcolors[currentColor].value;

    // Turn off the example headlight
    setHeadlightEnable(false);

    // Default to walk navigation
    setNavigationType(Walk);

    // Create the scene group
    Group scene = new Group();

    // BEGIN EXAMPLE TOPIC
    // Create application bounds
    BoundingSphere worldBounds = new BoundingSphere(new Point3d(0.00.0,
        0.0)// Center
        1000.0)// Extent

    // Set the background color and its application bounds
    background = new Background();
    background.setColor(color);
    background.setCapability(Background.ALLOW_COLOR_WRITE);
    background.setApplicationBounds(worldBounds);
    scene.addChild(background);
    // END EXAMPLE TOPIC

    // Build foreground geometry
    scene.addChild(new TowerScene(this));

    return scene;
  }

  //--------------------------------------------------------------
  //  USER INTERFACE
  //--------------------------------------------------------------

  //
  //  Main
  //
  public static void main(String[] args) {
    ExBackgroundColor ex = new ExBackgroundColor();
    ex.initialize(args);
    ex.buildUniverse();
    ex.showFrame();
  }

  //  Color menu choices
  private NameValue[] colors = new NameValue("White", White),
      new NameValue("Dark Gray", DarkGray),
      new NameValue("Black", Black)new NameValue("Dark Red", DarkRed),
      new NameValue("Dark Green", DarkGreen),
      new NameValue("Dark Blue", DarkBlue)};

  private int currentColor = 2;

  private CheckboxMenu colorMenu = null;

  //
  //  Initialize the GUI (application and applet)
  //
  public void initialize(String[] args) {
    // Initialize the window, menubar, etc.
    super.initialize(args);
    exampleFrame.setTitle("Java 3D Background Color Example");

    //
    //  Add a menubar menu to change node parameters
    //    Color -->
    //

    Menu m = new Menu("Background");

    colorMenu = new CheckboxMenu("Color", colors, currentColor, this);
    m.add(colorMenu);

    exampleMenuBar.add(m);
  }

  //
  //  Handle checkboxes and menu choices
  //
  public void checkboxChanged(CheckboxMenu menu, int check) {
    if (menu == colorMenu) {
      // Change the light color
      currentColor = check;
      Color3f color = (Color3fcolors[check].value;
      background.setColor(color);
      return;
    }

    // Handle all other checkboxes
    super.checkboxChanged(menu, check);
  }
}

//
//CLASS
//TowerScene - shapes and lights for a scene with towers
//
//DESCRIPTION
//This class builds a scene containing a cratered surface, a set of
//stone towers, plus appropriate lighting. The scene is used in several
//of the examples to provide content to affect with lights, background
//colors and images, and so forth.
//
//SEE ALSO
//ExBackgroundColor
//ExBackgroundImage
//ExBackgroundGeometry
//
//AUTHOR
//David R. Nadeau / San Diego Supercomputer Center
//

class TowerScene extends Group {
  private static final double[][] craters = {
  // x,z,radius are in a normalized -1.0 to 1.0 space
      // x z radius depth
      0.00.00.70.20 }0.30.30.50.20 },
      -0.30.10.60.20 }-0.20.40.40.20 },
      -0.9, -0.90.50.20 }0.40.50.30.10 },
      0.9, -0.20.40.10 }-0.80.10.20.10 },
      0.20.70.30.20 }0.5, -0.50.210.20 },
      0.8, -0.80.160.10 }-0.30.70.230.20 },
      0.50.50.220.10 }-0.70.80.150.10 },
      -0.5, -0.30.220.10 }0.20.20.150.10 },
      0.10.80.250.20 }0.40.90.280.09 },
      0.9, -0.10.230.10 }0.1, -0.00.330.08 },
      0.1, -0.90.230.20 }-1.00.80.130.15 },
      -0.90.70.100.15 }-0.20.10.100.16 },
      1.11.00.120.15 }0.90.50.130.14 },
      -0.1, -0.10.140.15 }-0.5, -0.50.100.13 },
      0.1, -0.40.100.15 }-0.4, -1.00.250.15 },
      0.41.00.250.15 }};

  public TowerScene(Component observer) {
    BoundingSphere worldBounds = new BoundingSphere(new Point3d(0.00.0,
        0.0)// Center
        1000.0)// Extent

    // Add a few lights
    AmbientLight ambient = new AmbientLight();
    ambient.setEnable(true);
    ambient.setColor(new Color3f(0.2f0.2f0.2f));
    ambient.setInfluencingBounds(worldBounds);
    addChild(ambient);

    DirectionalLight dir1 = new DirectionalLight();
    dir1.setEnable(true);
    dir1.setColor(new Color3f(1.0f0.15f0.15f));
    dir1.setDirection(new Vector3f(0.8f, -0.35f, -0.5f));
    dir1.setInfluencingBounds(worldBounds);
    addChild(dir1);

    DirectionalLight dir2 = new DirectionalLight();
    dir2.setEnable(true);
    dir2.setColor(new Color3f(0.15f0.15f1.0f));
    dir2.setDirection(new Vector3f(-0.7f, -0.35f0.5f));
    dir2.setInfluencingBounds(worldBounds);
    addChild(dir2);

    // Load textures
    TextureLoader texLoader = new TextureLoader("moon5.jpg", observer);
    Texture moon = texLoader.getTexture();
    if (moon == null)
      System.err.println("Cannot load moon5.jpg texture");
    else {
      moon.setBoundaryModeS(Texture.WRAP);
      moon.setBoundaryModeT(Texture.WRAP);
      moon.setMinFilter(Texture.NICEST);
      moon.setMagFilter(Texture.NICEST);
      moon.setMipMapMode(Texture.BASE_LEVEL);
      moon.setEnable(true);
    }

    texLoader = new TextureLoader("stonebrk2.jpg", observer);
    Texture stone = texLoader.getTexture();
    if (stone == null)
      System.err.println("Cannot load stonebrk2.jpg texture");
    else {
      stone.setBoundaryModeS(Texture.WRAP);
      stone.setBoundaryModeT(Texture.WRAP);
      stone.setMinFilter(Texture.NICEST);
      stone.setMagFilter(Texture.NICEST);
      stone.setMipMapMode(Texture.BASE_LEVEL);
      stone.setEnable(true);
    }

    //
    //  Build a rough terrain
    //
    Appearance moonApp = new Appearance();

    Material moonMat = new Material();
    moonMat.setAmbientColor(0.5f0.5f0.5f);
    moonMat.setDiffuseColor(1.0f1.0f1.0f);
    moonMat.setSpecularColor(0.0f0.0f0.0f);
    moonApp.setMaterial(moonMat);

    TextureAttributes moonTexAtt = new TextureAttributes();
    moonTexAtt.setTextureMode(TextureAttributes.MODULATE);
    moonTexAtt.setPerspectiveCorrectionMode(TextureAttributes.NICEST);
    moonApp.setTextureAttributes(moonTexAtt);

    if (moon != null)
      moonApp.setTexture(moon);

    CraterGrid grid = new CraterGrid(5050// grid dimensions
        1.01.0// grid spacing
        4.0// height exageration factor
        craters, // grid elevations
        moonApp)// grid appearance
    addChild(grid);

    //
    // Build several towers on the terrain
    //
    SharedGroup tower = new SharedGroup();
    Appearance towerApp = new Appearance();

    Material towerMat = new Material();
    towerMat.setAmbientColor(0.6f0.6f0.6f);
    towerMat.setDiffuseColor(1.0f1.0f1.0f);
    towerMat.setSpecularColor(0.0f0.0f0.0f);
    towerApp.setMaterial(towerMat);

    Transform3D tr = new Transform3D();
    tr.setScale(new Vector3d(4.04.01.0));

    TextureAttributes towerTexAtt = new TextureAttributes();
    towerTexAtt.setTextureMode(TextureAttributes.MODULATE);
    towerTexAtt.setPerspectiveCorrectionMode(TextureAttributes.NICEST);
    towerTexAtt.setTextureTransform(tr);
    towerApp.setTextureAttributes(towerTexAtt);

    if (stone != null)
      towerApp.setTexture(stone);

    Arch towerShape = new Arch(0.0// start Phi
        1.571// end Phi
        2// nPhi
        0.0// start Theta
        Math.PI * 2.0// end Theta
        5// nTheta
        3.0// start radius
        8.0// end radius
        0.0// start phi thickness
        0.0// end phi thickness
        towerApp)// appearance
    tower.addChild(towerShape);

    // Place towers
    Matrix3f rot = new Matrix3f();
    rot.setIdentity();

    TransformGroup tg = new TransformGroup(new Transform3D(rot,
        new Vector3d(2.0, -3.0, -8.0)1.0));
    tg.addChild(new Link(tower));
    addChild(tg);

    tg = new TransformGroup(new Transform3D(rot, new Vector3d(-1.0, -3.0,
        -6.0)0.5));
    tg.addChild(new Link(tower));
    addChild(tg);tg = new TransformGroup(new Transform3D(rot, new Vector3d(5.0, -3.0,
        -6.0)0.75));
    tg.addChild(new Link(tower));
    addChild(tg);

    tg = new TransformGroup(new Transform3D(rot, new Vector3d(1.0, -3.0,
        -3.0)0.35));
    tg.addChild(new Link(tower));
    addChild(tg);
  }
}

//
//CLASS
//Arch - generalized arch
//
//DESCRIPTION
//This class builds a generalized arch where incoming parameters
//specify the angle range in theta (around the equator of a sphere),
//the angle range in phi (north-south), the number of subdivisions
//in theta and phi, and optionally radii and outer-to-inner wall
//thickness variations as phi varies from its starting value to
//its ending value. If the thicknesses are 0.0, then only an outer
//surface is created.
//
//Using this class, you can create spheres with or without inner
//surfaces, hemisphers, quarter spheres, and arches stretched or
//compressed vertically.
//
//This is probably not as general as it could be, but it was enough
//for the purposes at hand.
//
//SEE ALSO
//ModernFire
//
//AUTHOR
//David R. Nadeau / San Diego Supercomputer Center
//
//

class Arch extends Group {
  // The shape
  private Shape3D arch = null;

  // Construct an arch
  public Arch() {
    // Default to a sphere
    this(0.0, Math.PI / 2.090.0, Math.PI, 171.01.00.00.0,
        new Appearance());
  }

  public Arch(Appearance app) {
    // Default to a sphere
    this(0.0, Math.PI / 2.090.0, Math.PI, 171.01.00.00.0, app);
  }

  public Arch(double startPhi, double endPhi, int nPhi, double startTheta,
      double endTheta, int nTheta, Appearance app) {
    // Default to constant radius, no thickness
    this(startPhi, endPhi, nPhi, startTheta, endTheta, nTheta, 1.01.0,
        0.00.0, app);
  }

  public Arch(double startPhi, double endPhi, int nPhi, double startTheta,
      double endTheta, int nTheta, double startPhiRadius,
      double endPhiRadius, double startPhiThickness,
      double endPhiThickness, Appearance app) {
    double theta, phi, radius, radius2, thickness;
    double x, y, z;
    double[] xyz = new double[3];
    float[] norm = new float[3];
    float[] tex = new float[3];

    // Compute some values for our looping
    double deltaTheta = (endTheta - startTheta(double) (nTheta - 1);
    double deltaPhi = (endPhi - startPhi(double) (nPhi - 1);
    double deltaTexX = 1.0 (double) (nTheta - 1);
    double deltaTexY = 1.0 (double) (nPhi - 1);
    double deltaPhiRadius = (endPhiRadius - startPhiRadius)
        (double) (nPhi - 1);
    double deltaPhiThickness = (endPhiThickness - startPhiThickness)
        (double) (nPhi - 1);

    boolean doThickness = true;
    if (startPhiThickness == 0.0 && endPhiThickness == 0.0)
      doThickness = false;

    //  Create geometry
    int vertexCount = nTheta * nPhi;
    if (doThickness)
      vertexCount *= 2;
    int indexCount = (nTheta - 1(nPhi - 14// Outer surface
    if (doThickness) {
      indexCount *= 2// plus inner surface
      indexCount += (nPhi - 12// plus left & right edges
    }

    IndexedQuadArray polys = new IndexedQuadArray(vertexCount,
        GeometryArray.COORDINATES | GeometryArray.NORMALS
            | GeometryArray.TEXTURE_COORDINATE_2, indexCount);

    //
    //  Compute coordinates, normals, and texture coordinates
    //
    theta = startTheta;
    tex[00.0f;
    int index = 0;
    for (int i = 0; i < nTheta; i++) {
      phi = startPhi;
      radius = startPhiRadius;
      thickness = startPhiThickness;
      tex[10.0f;

      for (int j = 0; j < nPhi; j++) {
        norm[0(float) (Math.cos(phi* Math.cos(theta));
        norm[1(float) (Math.sin(phi));
        norm[2(float) (-Math.cos(phi* Math.sin(theta));
        xyz[0= radius * norm[0];
        xyz[1= radius * norm[1];
        xyz[2= radius * norm[2];
        polys.setCoordinate(index, xyz);
        polys.setNormal(index, norm);
        polys.setTextureCoordinate(index, tex);
        index++;

        if (doThickness) {
          radius2 = radius - thickness;
          xyz[0= radius2 * norm[0];
          xyz[1= radius2 * norm[1];
          xyz[2= radius2 * norm[2];
          norm[0*= -1.0f;
          norm[1*= -1.0f;
          norm[2*= -1.0f;
          polys.setCoordinate(index, xyz);
          polys.setNormal(index, norm);
          polys.setTextureCoordinate(index, tex);
          index++;
        }

        phi += deltaPhi;
        radius += deltaPhiRadius;
        thickness += deltaPhiThickness;
        tex[1+= deltaTexY;
      }
      theta += deltaTheta;
      tex[0+= deltaTexX;
    }

    //
    //  Compute coordinate indexes
    //  (also used as normal and texture indexes)
    //
    index = 0;
    int phiRow = nPhi;
    int phiCol = 1;
    if (doThickness) {
      phiRow += nPhi;
      phiCol += 1;
    }
    int[] indices = new int[indexCount];

    // Outer surface
    int n;
    for (int i = 0; i < nTheta - 1; i++) {
      for (int j = 0; j < nPhi - 1; j++) {
        n = i * phiRow + j * phiCol;
        indices[index + 0= n;
        indices[index + 1= n + phiRow;
        indices[index + 2= n + phiRow + phiCol;
        indices[index + 3= n + phiCol;
        index += 4;
      }
    }

    // Inner surface
    if (doThickness) {
      for (int i = 0; i < nTheta - 1; i++) {
        for (int j = 0; j < nPhi - 1; j++) {
          n = i * phiRow + j * phiCol;
          indices[index + 0= n + 1;
          indices[index + 1= n + phiCol + 1;
          indices[index + 2= n + phiRow + phiCol + 1;
          indices[index + 3= n + phiRow + 1;
          index += 4;
        }
      }
    }

    // Edges
    if (doThickness) {
      for (int j = 0; j < nPhi - 1; j++) {
        n = j * phiCol;
        indices[index + 0= n;
        indices[index + 1= n + phiCol;
        indices[index + 2= n + phiCol + 1;
        indices[index + 3= n + 1;
        index += 4;
      }
      for (int j = 0; j < nPhi - 1; j++) {
        n = (nTheta - 1* phiRow + j * phiCol;
        indices[index + 0= n;
        indices[index + 1