SimpleTest.java Source code

Java tutorial

Introduction

Here is the source code for SimpleTest.java

Source

/*******************************************************************************
 * Copyright (C) 2001 Daniel Selman
 * 
 * First distributed with the book "Java 3D Programming" by Daniel Selman and
 * published by Manning Publications. http://manning.com/selman
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, version 2.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * The license can be found on the WWW at: http://www.fsf.org/copyleft/gpl.html
 * 
 * Or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite
 * 330, Boston, MA 02111-1307, USA.
 * 
 * Authors can be contacted at: Daniel Selman: daniel@selman.org
 * 
 * If you make changes you think others would like, please contact one of the
 * authors or someone at the www.j3d.org web site.
 ******************************************************************************/

import java.applet.Applet;

import javax.media.j3d.Alpha;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.PositionInterpolator;
import javax.media.j3d.Texture;
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.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;

/*
 * This example builds a simple Java 3D Application using the SUN utility
 * classes: MainFrame and SimpleUniverse. The example displays a moving sphere,
 * in front of a background image. It uses a texture image and one light to
 * increase the visual impact of the scene.
 */
public class SimpleTest extends Applet {
    /*
     * Create a simple Java 3D environment containing: a sphere (geometry), a
     * light,background geometry with an applied texture, and a behavior that
     * will move the sphere along the X-axis.
     */
    public SimpleTest() {
        // create the SimpleUniverse class that will
        // encapsulate the scene that we are building.
        // SimpleUniverse is a helper class (utility)
        // from SUN that is included with the core Java 3D
        // distribution.
        SimpleUniverse u = new SimpleUniverse();

        // create a BranchGroup. A BranchGroup is a node in
        // a Tree data structure that can have child nodes
        BranchGroup bgRoot = new BranchGroup();

        // create the Background node and add it to the SimpleUniverse
        u.addBranchGraph(createBackground());

        // create the behaviors to move the geometry along the X-axis.
        // The behavior is added as a child of the bgRoot node.
        // Anything add as a child of the tg node will be effected by the
        // behvior (will be moved along the X-axis).
        TransformGroup tg = createBehaviors(bgRoot);

        // add the Sphere geometry as a child of the tg
        // so that it will be moved along the X-axis.
        tg.addChild(createSceneGraph());

        // because the sphere was added at the 0,0,0 coordinate
        // and by default the viewer is also located at 0,0,0
        // we have to move the viewer back a little so that
        // she can see the scene.
        u.getViewingPlatform().setNominalViewingTransform();

        // add a light to the root BranchGroup to illuminate the scene
        addLights(bgRoot);

        // finally wire everything together by adding the root
        // BranchGroup to the SimpleUniverse
        u.addBranchGraph(bgRoot);
    }

    /*
     * Create the geometry for the scene. In this case we simply create a Sphere
     * (a built-in Java 3D primitive).
     */
    public BranchGroup createSceneGraph() {
        // create a parent BranchGroup node for the Sphere
        BranchGroup bg = new BranchGroup();

        // create an Appearance for the Sphere.
        // The Appearance object controls various rendering
        // options for the Sphere geometry.
        Appearance app = new Appearance();

        // assign a Material to the Appearance. For the Sphere
        // to respond to the light in the scene it must have a Material.
        // Assign some colors to the Material and a shininess setting
        // that controls how reflective the surface is to lighting.
        Color3f objColor = new Color3f(0.8f, 0.2f, 1.0f);
        Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
        app.setMaterial(new Material(objColor, black, objColor, black, 80.0f));

        // create a Sphere with a radius of 0.1
        // and associate the Appearance that we described.
        // the option GENERATE_NORMALS is required to ensure that the
        // Sphere responds correctly to lighting.
        Sphere sphere = new Sphere(0.1f, Primitive.GENERATE_NORMALS, app);

        // add the sphere to the BranchGroup to wire
        // it into the scene.
        bg.addChild(sphere);
        return bg;
    }

    /*
     * Add a directional light to the BranchGroup.
     */
    public void addLights(BranchGroup bg) {
        // create the color for the light
        Color3f color = new Color3f(1.0f, 1.0f, 0.0f);

        // create a vector that describes the direction that
        // the light is shining.
        Vector3f direction = new Vector3f(-1.0f, -1.0f, -1.0f);

        // create the directional light with the color and direction
        DirectionalLight light = new DirectionalLight(color, direction);

        // set the volume of influence of the light.
        // Only objects within the Influencing Bounds
        // will be illuminated.
        light.setInfluencingBounds(getBoundingSphere());

        // add the light to the BranchGroup
        bg.addChild(light);
    }

    /*
     * Create some Background geometry to use as a backdrop for the application.
     * Here we create a Sphere that will enclose the entire scene and apply a
     * texture image onto the inside of the Sphere to serve as a graphical
     * backdrop for the scene.
     */
    public BranchGroup createBackground() {
        // create a parent BranchGroup for the Background
        BranchGroup backgroundGroup = new BranchGroup();

        // create a new Background node
        Background back = new Background();

        // set the range of influence of the background
        back.setApplicationBounds(getBoundingSphere());

        // create a BranchGroup that will hold
        // our Sphere geometry
        BranchGroup bgGeometry = new BranchGroup();

        // create an appearance for the Sphere
        Appearance app = new Appearance();

        // load a texture image using the Java 3D texture loader
        Texture tex = new TextureLoader("back.jpg", this).getTexture();

        // apply the texture to the Appearance
        app.setTexture(tex);

        // create the Sphere geometry with radius 1.0
        // we tell the Sphere to generate texture coordinates
        // to enable the texture image to be rendered
        // and because we are *inside* the Sphere we have to generate
        // Normal coordinates inwards or the Sphere will not be visible.
        Sphere sphere = new Sphere(1.0f, Primitive.GENERATE_TEXTURE_COORDS | Primitive.GENERATE_NORMALS_INWARD,
                app);

        // start wiring everything together
        // add the Sphere to its parent BranchGroup
        bgGeometry.addChild(sphere);

        // assign the BranchGroup to the Background as geometry.
        back.setGeometry(bgGeometry);

        // add the Background node to its parent BranchGroup
        backgroundGroup.addChild(back);

        return backgroundGroup;
    }

    /*
     * Create a behavior to move child nodes along the X-axis. The behavior is
     * added to the BranchGroup bg, whereas any nodes added to the returned
     * TransformGroup will be effected by the behavior.
     */
    public TransformGroup createBehaviors(BranchGroup bg) {
        // create a TransformGroup.
        //
        // A TransformGroup is a Group node (can have children)
        // and contains a Transform3D member.
        //
        // The Transform3D member contains a 4x4 transformation matrix
        // that is applied during rendering to all the TransformGroup's
        // child nodes. The 4x4 matrix can describe:
        // scaling, translation and rotation in one neat package!

        // enable the TRANSFORM_WRITE capability so that
        // our behavior code can modify it at runtime
        TransformGroup objTrans = new TransformGroup();
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        // create a new Transform3D that will describe
        // the direction we want to move.
        Transform3D xAxis = new Transform3D();

        // create an Alpha object.
        // The Alpha object describes a function against time.
        // The Alpha will output a value that ranges between 0 and 1
        // using the time parameters (in milliseconds).
        Alpha xAlpha = new Alpha(-1, Alpha.DECREASING_ENABLE | Alpha.INCREASING_ENABLE, 1000, 1000, 5000, 1000,
                1000, 10000, 2000, 4000);

        // create a PositionInterpolator
        // The PositionInterpolator will modify the translation components
        // of a TransformGroup's Transform3D (objTrans) based on the output
        // from the Alpha. In this case the movement will range from
        // -0.8 along the X-axis with Alpha=0 to X=0.8 when Alpha=1.
        PositionInterpolator posInt = new PositionInterpolator(xAlpha, objTrans, xAxis, -0.8f, 0.8f);

        // set the range of influence of the PositionInterpolator
        posInt.setSchedulingBounds(getBoundingSphere());

        // wire the PositionInterpolator into its parent
        // TransformGroup. Just like rendering nodes behaviors
        // must be added to the scenegraph.
        objTrans.addChild(posInt);

        // add the TransformGroup to its parent BranchGroup
        bg.addChild(objTrans);

        // we return the TransformGroup with the
        // behavior attached so that we can add nodes to it
        // (which will be effected by the PositionInterpolator).
        return objTrans;
    }

    /*
     * Return a BoundingSphere that describes the volume of the scene.
     */
    BoundingSphere getBoundingSphere() {
        return new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 200.0);
    }

    /*
     * main entry point for the Application.
     */
    public static void main(String[] args) {
        SimpleTest simpleTest = new SimpleTest();
    }
}