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
Java Network
Java Forums
Java 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: 1016
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:
 
 
 
Collision Detection with Java3D E-mail
User Rating: / 27
PoorBest 

This class demonstrates the use of the CollisionDetector class to perform processing when objects collide. When this program is run the white cube can be selected and moved by dragging on it with the right mouse button. You should notice that there is a problem if the movable cube comes into contact with both of the static cubes at one time. This problem is solved in another tip with the title: "Collision Detection with Java3D - 2".


Image

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Bounds;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.IndexedQuadArray;
import javax.media.j3d.Locale;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.PhysicalBody;
import javax.media.j3d.PhysicalEnvironment;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.View;
import javax.media.j3d.ViewPlatform;
import javax.media.j3d.VirtualUniverse;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnCollisionEntry;
import javax.media.j3d.WakeupOnCollisionExit;
import javax.media.j3d.WakeupOnCollisionMovement;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.picking.behaviors.PickTranslateBehavior;

/**
 * This class demonstrates the use of the CollisionDetector class to perform
 * processing when objects collide. When this program is run the white cube can
 * be selected and moved by dragging on it with the right mouse button. You
 * should notice that there is a problem if the movable cube comes into contact
 * with both of the static cubes at one time. A way round this is given in the
 * SimpleCollision2 application.
 
 @see CollisionDetector
 @see SimpleCollision2
 @author I.J.Palmer
 @version 1.0
 */
public class SimpleCollision extends Frame implements ActionListener {
  protected Canvas3D myCanvas3D = new Canvas3D(null);

  protected Button exitButton = new Button("Exit");

  protected BoundingSphere bounds = new BoundingSphere(new Point3d(0.00.0,
      0.0)100.0);

  /** Transform for the left cube. */
  protected TransformGroup leftGroup;

  /** Transform for the right cube */
  protected TransformGroup rightGroup;

  /**
   * Transform for the movable cube. This has read, write and pick reporting
   * capabilities enabled.
   */
  protected TransformGroup moveGroup;

  /** A transform to change the size of the movable cube. */
  protected TransformGroup scaleGroup;

  /** The left static cube. */
  protected Shape3D leftCube;

  /** The right static cube. */
  protected Shape3D rightCube;

  /** The movable cube that will collide with the other two cubes */
  protected Shape3D moveCube;

  /**
   * This builds the view branch of the scene graph.
   */
  protected BranchGroup buildViewBranch(Canvas3D c) {
    BranchGroup viewBranch = new BranchGroup();
    Transform3D viewXfm = new Transform3D();
    viewXfm.set(new Vector3f(0.0f0.0f10.0f));
    TransformGroup viewXfmGroup = new TransformGroup(viewXfm);
    ViewPlatform myViewPlatform = new ViewPlatform();
    PhysicalBody myBody = new PhysicalBody();
    PhysicalEnvironment myEnvironment = new PhysicalEnvironment();
    viewXfmGroup.addChild(myViewPlatform);
    viewBranch.addChild(viewXfmGroup);
    View myView = new View();
    myView.addCanvas3D(c);
    myView.attachViewPlatform(myViewPlatform);
    myView.setPhysicalBody(myBody);
    myView.setPhysicalEnvironment(myEnvironment);
    return viewBranch;
  }

  /**
   * This adds some lights to the content branch of the scene graph.
   
   @param b
   *            The BranchGroup to add the lights to.
   */
  protected void addLights(BranchGroup b) {
    Color3f ambLightColour = new Color3f(0.5f0.5f0.5f);
    AmbientLight ambLight = new AmbientLight(ambLightColour);
    ambLight.setInfluencingBounds(bounds);
    Color3f dirLightColour = new Color3f(1.0f1.0f1.0f);
    Vector3f dirLightDir = new Vector3f(-1.0f, -1.0f, -1.0f);
    DirectionalLight dirLight = new DirectionalLight(dirLightColour,
        dirLightDir);
    dirLight.setInfluencingBounds(bounds);
    b.addChild(ambLight);
    b.addChild(dirLight);
  }

  /**
   * Creates the content branch of the scene graph.
   
   @return BranchGroup with content attached.
   */
  protected BranchGroup buildContentBranch() {
    //First create a different appearance for each cube
    Appearance app1 = new Appearance();
    Appearance app2 = new Appearance();
    Appearance app3 = new Appearance();
    Color3f ambientColour1 = new Color3f(1.0f0.0f0.0f);
    Color3f ambientColour2 = new Color3f(1.0f1.0f0.0f);
    Color3f ambientColour3 = new Color3f(1.0f1.0f1.0f);
    Color3f emissiveColour = new Color3f(0.0f0.0f0.0f);
    Color3f specularColour = new Color3f(1.0f1.0f1.0f);
    Color3f diffuseColour1 = new Color3f(1.0f0.0f0.0f);
    Color3f diffuseColour2 = new Color3f(1.0f1.0f0.0f);
    Color3f diffuseColour3 = new Color3f(1.0f1.0f1.0f);
    float shininess = 20.0f;
    app1.setMaterial(new Material(ambientColour1, emissiveColour,
        diffuseColour1, specularColour, shininess));
    app2.setMaterial(new Material(ambientColour2, emissiveColour,
        diffuseColour2, specularColour, shininess));
    app3.setMaterial(new Material(ambientColour3, emissiveColour,
        diffuseColour3, specularColour, shininess));

    //Create the vertex data for the cube. Since each shape is
    //a cube we can use the same vertex data for each cube
    IndexedQuadArray indexedCube = new IndexedQuadArray(8,
        IndexedQuadArray.COORDINATES | IndexedQuadArray.NORMALS, 24);
    Point3f[] cubeCoordinates = new Point3f(1.0f1.0f1.0f),
        new Point3f(-1.0f1.0f1.0f),
        new Point3f(-1.0f, -1.0f1.0f),
        new Point3f(1.0f, -1.0f1.0f)new Point3f(1.0f1.0f, -1.0f),
        new Point3f(-1.0f1.0f, -1.0f),
        new Point3f(-1.0f, -1.0f, -1.0f),
        new Point3f(1.0f, -1.0f, -1.0f) };
    Vector3f[] cubeNormals = new Vector3f(0.0f0.0f1.0f),
        new Vector3f(0.0f0.0f, -1.0f),
        new Vector3f(1.0f0.0f0.0f),
        new Vector3f(-1.0f0.0f0.0f),
        new Vector3f(0.0f1.0f0.0f)new Vector3f(0.0f, -1.0f0.0f) };
    int cubeCoordIndices[] 012376540374562,
        10451673};
    int cubeNormalIndices[] 00001111222233,
        334444555};
    indexedCube.setCoordinates(0, cubeCoordinates);
    indexedCube.setNormals(0, cubeNormals);
    indexedCube.setCoordinateIndices(0, cubeCoordIndices);
    indexedCube.setNormalIndices(0, cubeNormalIndices);

    //Create the three cubes
    leftCube = new Shape3D(indexedCube, app1);
    rightCube = new Shape3D(indexedCube, app2);
    moveCube = new Shape3D(indexedCube, app3);

    //Define the user data so that we can print out the
    //name of the colliding cube.
    leftCube.setUserData(new String("left cube"));
    rightCube.setUserData(new String("right cube"));

    //Create the content branch and add the lights
    BranchGroup contentBranch = new BranchGroup();
    addLights(contentBranch);

    //Create and set up the movable cube's TransformGroup.
    //This scales and translates the cube and then sets the
    // read, write and pick reporting capabilities.
    Transform3D moveXfm = new Transform3D();
    moveXfm.set(0.7new Vector3d(0.02.01.0));
    moveGroup = new TransformGroup(moveXfm);
    moveGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    moveGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    moveGroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING);

    //Create the left cube's TransformGroup
    Transform3D leftGroupXfm = new Transform3D();
    leftGroupXfm.set(new Vector3d(-1.50.00.0));
    leftGroup = new TransformGroup(leftGroupXfm);

    //Create the right cube's TransformGroup
    Transform3D rightGroupXfm = new Transform3D();
    rightGroupXfm.set(new Vector3d(1.50.00.0));
    rightGroup = new TransformGroup(rightGroupXfm);

    //Add the behaviour to allow us to move the cube
    PickTranslateBehavior pickTranslate = new PickTranslateBehavior(
        contentBranch, myCanvas3D, bounds);
    contentBranch.addChild(pickTranslate);

    //Add our CollisionDetector class to detect collisions with
    //the movable cube.
    CollisionDetector myColDet = new CollisionDetector(moveCube, bounds);
    contentBranch.addChild(myColDet);

    //Create the content branch hierarchy.
    contentBranch.addChild(moveGroup);
    contentBranch.addChild(leftGroup);
    contentBranch.addChild(rightGroup);
    moveGroup.addChild(moveCube);
    leftGroup.addChild(leftCube);
    rightGroup.addChild(rightCube);

    return contentBranch;

  }

  /**
   * Process the exit button action to exit the application.
   */
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == exitButton) {
      dispose();
      System.exit(0);
    }
  }

  public SimpleCollision() {
    VirtualUniverse myUniverse = new VirtualUniverse();
    Locale myLocale = new Locale(myUniverse);
    myLocale.addBranchGraph(buildViewBranch(myCanvas3D));
    myLocale.addBranchGraph(buildContentBranch());
    setTitle("SimpleWorld");
    setSize(400