ExBackgroundImage - illustrate use of background images : Background « 3D « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » 3D » BackgroundScreenshots 
ExBackgroundImage - illustrate use of background images

//
//CLASS
//ExBackgroundImage - illustrate use of background images
//
//LESSON
//Add a Background node to place an background image behind geometry.
//
//SEE ALSO
//ExBackgroundColor
//ExBackgroundGeometry
//
//AUTHOR
//David R. Nadeau / San Diego Supercomputer Center
//

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.ImageComponent2D;
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 ExBackgroundImage extends Java3DFrame {
  //--------------------------------------------------------------
  //  SCENE CONTENT
  //--------------------------------------------------------------

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

  //
  //  Build scene
  //
  public Group buildScene() {
    // Get the current image
    ImageComponent2D image = imageComponents[currentImage];

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

    // Default to walk navigation
    setNavigationType(Walk);

    // Build the scene root
    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.setImage(image);
    background.setCapability(Background.ALLOW_IMAGE_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) {
    ExBackgroundImage ex = new ExBackgroundImage();
    ex.initialize(args);
    ex.buildUniverse();
    ex.showFrame();
  }

  //  Image menu choices
  private NameValue[] images = new NameValue("None"null),
      new NameValue("Stars""stars2.jpg"),
      new NameValue("Red Clouds""oddclouds.jpg"),
      new NameValue("White Clouds""clouds.jpg")};

  private int currentImage = 0;

  private ImageComponent2D[] imageComponents = null;

  private CheckboxMenu imageMenu = 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 Image Example");

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

    Menu m = new Menu("Background");

    imageMenu = new CheckboxMenu("Image", images, currentImage, this);
    m.add(imageMenu);

    exampleMenuBar.add(m);

    // Preload the background images
    //   Use the texture loading utility to read in the image
    //   files and process them into an ImageComponent2D
    //   for use in the Background node.
    if (debug)
      System.err.println("  background images...");
    TextureLoader texLoader = null;
    String value = null;
    imageComponents = new ImageComponent2D[images.length];

    for (int i = 0; i < images.length; i++) {
      value = (Stringimages[i].value;
      if (value == null) {
        imageComponents[inull;
        continue;
      }
      texLoader = new TextureLoader(value, this);
      imageComponents[i= texLoader.getImage();
      // Component could be null if image couldn't be loaded
    }
  }

  //
  //  Handle checkboxes and menu choices
  //
  public void checkboxChanged(CheckboxMenu menu, int check) {
    if (menu == imageMenu) {
      // Change the background image
      currentImage = check;
      ImageComponent2D image = imageComponents[check];
      background.setImage(image);
      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;