Skip to main content

KeyNavigatorApp

6 replies [Last post]
adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

For some reason the code below doesn't work:
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.IndexedTriangleArray;
import javax.media.j3d.LineArray;
import javax.media.j3d.Link;
import javax.media.j3d.Shape3D;
import javax.media.j3d.SharedGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;
// KeyNavigatorApp renders a simple landscape
public class NewEmpty extends Applet {
Shape3D createPyramid() {
IndexedTriangleArray pyGeom = new IndexedTriangleArray(5,
GeometryArray.COORDINATES | GeometryArray.COLOR_3, 12);
pyGeom.setCoordinate(0, new Point3f(0.0f, 0.7f, 0.0f));
pyGeom.setCoordinate(1, new Point3f(-0.4f, 0.0f, -0.4f));
pyGeom.setCoordinate(2, new Point3f(-0.4f, 0.0f, 0.4f));
pyGeom.setCoordinate(3, new Point3f(0.4f, 0.0f, 0.4f));
pyGeom.setCoordinate(4, new Point3f(0.4f, 0.0f, -0.4f));
pyGeom.setCoordinateIndex(0, 0);
pyGeom.setCoordinateIndex(1, 1);
pyGeom.setCoordinateIndex(2, 2);
pyGeom.setCoordinateIndex(3, 0);
pyGeom.setCoordinateIndex(4, 2);
pyGeom.setCoordinateIndex(5, 3);
pyGeom.setCoordinateIndex(6, 0);
pyGeom.setCoordinateIndex(7, 3);
pyGeom.setCoordinateIndex(8, 4);
pyGeom.setCoordinateIndex(9, 0);
pyGeom.setCoordinateIndex(10, 4);
pyGeom.setCoordinateIndex(11, 1);
Color3f c = new Color3f(0.6f, 0.5f, 0.55f);
pyGeom.setColor(0, c);
pyGeom.setColor(1, c);
pyGeom.setColor(2, c);
pyGeom.setColor(3, c);
pyGeom.setColor(4, c);
Shape3D pyramid = new Shape3D(pyGeom);
return pyramid;
}
Shape3D createLand() {
LineArray landGeom = new LineArray(44, GeometryArray.COORDINATES
| GeometryArray.COLOR_3);
float l = -50.0f;
for (int c = 0; c < 44; c += 4) {
landGeom.setCoordinate(c + 0, new Point3f(-50.0f, 0.0f, l));
landGeom.setCoordinate(c + 1, new Point3f(50.0f, 0.0f, l));
landGeom.setCoordinate(c + 2, new Point3f(l, 0.0f, -50.0f));
landGeom.setCoordinate(c + 3, new Point3f(l, 0.0f, 50.0f));
l += 10.0f;
}
Color3f c = new Color3f(0.1f, 0.8f, 0.1f);
for (int i = 0; i < 44; i++)
landGeom.setColor(i, c);
return new Shape3D(landGeom);
}
public BranchGroup createSceneGraph(SimpleUniverse su) {
// Create the root of the branch graph
TransformGroup vpTrans = null;
BranchGroup objRoot = new BranchGroup();
Vector3f translate = new Vector3f();
Transform3D T3D = new Transform3D();
TransformGroup TG = null;
objRoot.addChild(createLand());
SharedGroup share = new SharedGroup();
share.addChild(createPyramid());
float[][] position = { { 0.0f, 0.0f, -3.0f }, { 6.0f, 0.0f, 0.0f },
{ 6.0f, 0.0f, 6.0f }, { 3.0f, 0.0f, -10.0f },
{ 13.0f, 0.0f, -30.0f }, { -13.0f, 0.0f, 30.0f },
{ -13.0f, 0.0f, 23.0f }, { 13.0f, 0.0f, 3.0f } };
for (int i = 0; i < position.length; i++) {
translate.set(position[i]);
T3D.setTranslation(translate);
TG = new TransformGroup(T3D);
TG.addChild(new Link(share));
objRoot.addChild(TG);
}
vpTrans = su.getViewingPlatform().getViewPlatformTransform();
translate.set(0.0f, 0.3f, 0.0f);
T3D.setTranslation(translate);
vpTrans.setTransform(T3D);
KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);
keyNavBeh
.setSchedulingBounds(new BoundingSphere(new Point3d(), 1000.0));
objRoot.addChild(keyNavBeh);
// Let Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
} // end of CreateSceneGraph method of KeyNavigatorApp
public NewEmpty() {
setLayout(new BorderLayout());
Canvas3D canvas3D = new Canvas3D(null);
add("Center", canvas3D);
// SimpleUniverse is a Convenience Utility class
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
BranchGroup scene = createSceneGraph(simpleU);
simpleU.addBranchGraph(scene);
} // end of KeyNavigatorApp (constructor)
// The following allows this to be run as an application
// as well as an applet
public static void main(String[] args) {
System.out
.print("KeyNavigatorApp.java \n- a demonstration of the KeyNavigatorBehavior ");
System.out
.println("class to provide keyboard navigation in a Java 3D scene.");
System.out
.println("When the app loads, you can use the arrow keys to move.");
System.out
.println("This is an example progam from The Java 3D API Tutorial.");
System.out.println("The Java 3D Tutorial is available on the web at:");
System.out.println("http://www.sun.com/desktop/java3d/collateral");
Frame frame = new MainFrame(new NewEmpty(), 256, 256);
} // end of main (method of KeyNavigatorApp)
} // end of class KeyNavigatorApp

I GET THE FOLLOWING MESSAGE:
The Java 3D Tutorial is available on the web at:
http://www.sun.com/desktop/java3d/collateral
Exception in thread "main" java.lang.NullPointerException: Canvas3D: null GraphicsConfiguration
at javax.media.j3d.Canvas3D.checkForValidGraphicsConfig(Canvas3D.java:963)
at javax.media.j3d.Canvas3D.<init>(Canvas3D.java:1006)
at NewEmpty.<init>(NewEmpty.java:127)
at NewEmpty.main(NewEmpty.java:152)
Java Result: 1
BUILD SUCCESSFUL (total time: 3 seconds)

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
itpedersen
Offline
Joined: 2011-02-14
Points: 0

I have clean the code slightly and now it is running fine. I have removed the applet element. The simple univers object is enough
Hope it is ok.
The code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package javaapplication7;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.IndexedTriangleArray;
import javax.media.j3d.LineArray;
import javax.media.j3d.Link;
import javax.media.j3d.Shape3D;
import javax.media.j3d.SharedGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;
// KeyNavigatorApp renders a simple landscape
public class Main
{
Shape3D createPyramid()
{
IndexedTriangleArray pyGeom = new IndexedTriangleArray(5,
GeometryArray.COORDINATES | GeometryArray.COLOR_3, 12);
pyGeom.setCoordinate(0, new Point3f(0.0f, 0.7f, 0.0f));
pyGeom.setCoordinate(1, new Point3f(-0.4f, 0.0f, -0.4f));
pyGeom.setCoordinate(2, new Point3f(-0.4f, 0.0f, 0.4f));
pyGeom.setCoordinate(3, new Point3f(0.4f, 0.0f, 0.4f));
pyGeom.setCoordinate(4, new Point3f(0.4f, 0.0f, -0.4f));
pyGeom.setCoordinateIndex(0, 0);
pyGeom.setCoordinateIndex(1, 1);
pyGeom.setCoordinateIndex(2, 2);
pyGeom.setCoordinateIndex(3, 0);
pyGeom.setCoordinateIndex(4, 2);
pyGeom.setCoordinateIndex(5, 3);
pyGeom.setCoordinateIndex(6, 0);
pyGeom.setCoordinateIndex(7, 3);
pyGeom.setCoordinateIndex(8, 4);
pyGeom.setCoordinateIndex(9, 0);
pyGeom.setCoordinateIndex(10, 4);
pyGeom.setCoordinateIndex(11, 1);
Color3f c = new Color3f(0.6f, 0.5f, 0.55f);
pyGeom.setColor(0, c);
pyGeom.setColor(1, c);
pyGeom.setColor(2, c);
pyGeom.setColor(3, c);
pyGeom.setColor(4, c);
Shape3D pyramid = new Shape3D(pyGeom);
return pyramid;
}
Shape3D createLand() {
LineArray landGeom = new LineArray(44, GeometryArray.COORDINATES
| GeometryArray.COLOR_3);
float l = -50.0f;
for (int c = 0; c < 44; c += 4) {
landGeom.setCoordinate(c + 0, new Point3f(-50.0f, 0.0f, l));
landGeom.setCoordinate(c + 1, new Point3f(50.0f, 0.0f, l));
landGeom.setCoordinate(c + 2, new Point3f(l, 0.0f, -50.0f));
landGeom.setCoordinate(c + 3, new Point3f(l, 0.0f, 50.0f));
l += 10.0f;
}
Color3f c = new Color3f(0.1f, 0.8f, 0.1f);
for (int i = 0; i < 44; i++)
landGeom.setColor(i, c);
return new Shape3D(landGeom);
}
public BranchGroup createSceneGraph(SimpleUniverse su) {
// Create the root of the branch graph
TransformGroup vpTrans = null;
BranchGroup objRoot = new BranchGroup();
Vector3f translate = new Vector3f();
Transform3D T3D = new Transform3D();
TransformGroup TG = null;
objRoot.addChild(createLand());
SharedGroup share = new SharedGroup();
share.addChild(createPyramid());
float[][] position = { { 0.0f, 0.0f, -3.0f }, { 6.0f, 0.0f, 0.0f },
{ 6.0f, 0.0f, 6.0f }, { 3.0f, 0.0f, -10.0f },
{ 13.0f, 0.0f, -30.0f }, { -13.0f, 0.0f, 30.0f },
{ -13.0f, 0.0f, 23.0f }, { 13.0f, 0.0f, 3.0f } };
for (int i = 0; i < position.length; i++) {
translate.set(position[i]);
T3D.setTranslation(translate);
TG = new TransformGroup(T3D);
TG.addChild(new Link(share));
objRoot.addChild(TG);
}
vpTrans = su.getViewingPlatform().getViewPlatformTransform();
translate.set(0.0f, 0.3f, 0.0f);
T3D.setTranslation(translate);
vpTrans.setTransform(T3D);
KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);
keyNavBeh
.setSchedulingBounds(new BoundingSphere(new Point3d(), 1000.0));
objRoot.addChild(keyNavBeh);
// Let Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
} // end of CreateSceneGraph method of KeyNavigatorApp
public Main()
{

// SimpleUniverse is a Convenience Utility class
SimpleUniverse simpleU = new SimpleUniverse();
BranchGroup scene = createSceneGraph(simpleU);
simpleU.addBranchGraph(scene);
} // end of KeyNavigatorApp (constructor)
// The following allows this to be run as an application
// as well as an applet
public static void main(String[] args)
{
new Main();
} // end of main (method of KeyNavigatorApp)
} // end of class KeyNavigatorApp

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

Thank you so much. That's great but i seem tohave the same problem at http://www.java-tips.org/other-api-tips/java3d/how-to-use-3d-sound-in-ja...
trying to load their SimpleSounds program :

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 javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BackgroundSound;
import javax.media.j3d.BoundingLeaf;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Locale;
import javax.media.j3d.Material;
import javax.media.j3d.MediaContainer;
import javax.media.j3d.PhysicalBody;
import javax.media.j3d.PhysicalEnvironment;
import javax.media.j3d.PointSound;
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.vecmath.Color3f;
import javax.vecmath.Point2f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.audioengines.javasound.JavaSoundMixer;
import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
import com.sun.j3d.utils.geometry.Box;

/**
* This application demonstrates the use of 3D sound. It loads three sounds:
* loop3.wav is an ambient background sound and loop1.wav and loop2.wav are
* point sounds. The two point sounds can be switched on and off use AWT
* buttons. The user can navigate around the scene using the keyboard.
*
* @author I.J.Palmer
* @version 1.0
*/
public class SimpleSounds extends Frame implements ActionListener {
protected Canvas3D myCanvas3D = new Canvas3D(null);

/** The exit button to quit the application */
protected Button exitButton = new Button("Exit");

/** The button to switch on and off the first sound */
protected Button sound1Button = new Button("Sound 1");

/** The button to switch on and off the second sound */
protected Button sound2Button = new Button("Sound 2");

protected BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0,
0.0), 10000.0);

//Create the two point sounds
PointSound sound1 = new PointSound();

PointSound sound2 = new PointSound();

/**
* Build the view branch of the scene graph. In this case a key navigation
* utility object is created and associated with the view transform so that
* the view can be changed via the keyboard.
*
* @return BranchGroup that is the root of the view branch
*/
protected BranchGroup buildViewBranch(Canvas3D c) {
BranchGroup viewBranch = new BranchGroup();
Transform3D viewXfm = new Transform3D();
viewXfm.set(new Vector3f(0.0f, 0.0f, 30.0f));
TransformGroup viewXfmGroup = new TransformGroup(viewXfm);
viewXfmGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
viewXfmGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
ViewPlatform myViewPlatform = new ViewPlatform();
BoundingSphere movingBounds = new BoundingSphere(new Point3d(0.0, 0.0,
0.0), 100.0);
BoundingLeaf boundLeaf = new BoundingLeaf(movingBounds);
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);
KeyNavigatorBehavior keyNav = new KeyNavigatorBehavior(viewXfmGroup);
keyNav.setSchedulingBounds(movingBounds);
viewBranch.addChild(keyNav);
//Create a sounds mixer to use our sounds with
//and initialise it
JavaSoundMixer myMixer = new JavaSoundMixer(myEnvironment);
myMixer.initialize();
return viewBranch;
}

/**
* Add some lights to the scene graph
*
* @param b
* BranchGroup that the lights are added to
*/
protected void addLights(BranchGroup b) {
Color3f ambLightColour = new Color3f(0.5f, 0.5f, 0.5f);
AmbientLight ambLight = new AmbientLight(ambLightColour);
ambLight.setInfluencingBounds(bounds);
Color3f dirLightColour = new Color3f(1.0f, 1.0f, 1.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);
}

/**
* This adds a continuous background sound to the branch group.
*
* @param b
* BranchGroup to add the sound to.
* @param soundFile
* String that is the name of the sound file.
*/
protected void addBackgroundSound(BranchGroup b, String soundFile) {
//Create a media container to load the file
MediaContainer droneContainer = new MediaContainer(soundFile);
//Create the background sound from the media container
BackgroundSound drone = new BackgroundSound(droneContainer, 1.0f);
//Activate the sound
drone.setSchedulingBounds(bounds);
drone.setEnable(true);
//Set the sound to loop forever
drone.setLoop(BackgroundSound.INFINITE_LOOPS);
//Add it to the group
b.addChild(drone);
}

/**
* Add a sound to the transform group. This takes a point sound object and
* loads into it a sounds from a given file. The edge of the sound's extent
* is also defined in a parameter.
*
* @param tg
* TransformGroup that the sound is to be added to
* @param sound
* PointSound to be used
* @param soundFile
* String that is the name of the sound file to be loaded
* @param edge
* float that represents the sound's maximum extent
*/
protected void addObjectSound(TransformGroup tg, PointSound sound,
String soundFile, float edge) {
//First we get the current transform so that we can
//position the sound in the same place
Transform3D objXfm = new Transform3D();
Vector3f objPosition = new Vector3f();
tg.getTransform(objXfm);
objXfm.get(objPosition);
//Create the media container to load the sound
MediaContainer soundContainer = new MediaContainer(soundFile);
//Use the loaded data in the sound
sound.setSoundData(soundContainer);
sound.setInitialGain(1.0f);
//Set the position to that of the given transform
sound.setPosition(new Point3f(objPosition));
//Allow use to switch the sound on and off
sound.setCapability(PointSound.ALLOW_ENABLE_READ);
sound.setCapability(PointSound.ALLOW_ENABLE_WRITE);
sound.setSchedulingBounds(bounds);
//Set it off to start with
sound.setEnable(false);
//Set it to loop forever
sound.setLoop(BackgroundSound.INFINITE_LOOPS);
//Use the edge value to set to extent of the sound
Point2f[] attenuation = { new Point2f(0.0f, 1.0f),
new Point2f(edge, 0.1f) };
sound.setDistanceGain(attenuation);
//Add the sound to the transform group
tg.addChild(sound);
}

protected BranchGroup buildContentBranch() {
//Create the appearance
Appearance app = new Appearance();
Color3f ambientColour = new Color3f(1.0f, 0.0f, 0.0f);
Color3f emissiveColour = new Color3f(0.0f, 0.0f, 0.0f);
Color3f specularColour = new Color3f(1.0f, 1.0f, 1.0f);
Color3f diffuseColour = new Color3f(1.0f, 0.0f, 0.0f);
float shininess = 20.0f;
app.setMaterial(new Material(ambientColour, emissiveColour,
diffuseColour, specularColour, shininess));
//Make the cube
Box myCube = new Box(1.0f, 1.0f, 1.0f, app);

TransformGroup cubeGroup = new TransformGroup();

BranchGroup contentBranch = new BranchGroup();
addLights(contentBranch);
addObjectSound(cubeGroup, sound1, new String("file:./loop1.wav"), 10.0f);
addObjectSound(cubeGroup, sound2, new String("file:./loop2.wav"), 20.0f);
addBackgroundSound(contentBranch, new String("file:./loop3.wav"));

cubeGroup.addChild(myCube);
contentBranch.addChild(cubeGroup);
return contentBranch;

}

public void actionPerformed(ActionEvent e) {
if (e.getSource() == exitButton) {
dispose();
System.exit(0);
} else if (e.getSource() == sound1Button) {
if (sound1.getEnable())
sound1.setEnable(false);
else
sound1.setEnable(true);
} else if (e.getSource() == sound2Button) {
sound2.setEnable(!sound2.getEnable());
}
}

public SimpleSounds() {
VirtualUniverse myUniverse = new VirtualUniverse();
Locale myLocale = new Locale(myUniverse);
// buildUniverse(myCanvas3D);
myLocale.addBranchGraph(buildContentBranch());
myLocale.addBranchGraph(buildViewBranch(myCanvas3D));
setTitle("SimpleSounds");
setSize(400, 400);
setLayout(new BorderLayout());
Panel bottom = new Panel();
bottom.add(sound1Button);
bottom.add(sound2Button);
bottom.add(exitButton);
add(BorderLayout.CENTER, myCanvas3D);
add(BorderLayout.SOUTH, bottom);
exitButton.addActionListener(this);
sound1Button.addActionListener(this);
sound2Button.addActionListener(this);
setVisible(true);
}

public static void main(String[] args) {
SimpleSounds sw = new SimpleSounds();
}
}

i get the following :

run:
Exception in thread "main" java.lang.NullPointerException: Canvas3D: null GraphicsConfiguration
at javax.media.j3d.Canvas3D.checkForValidGraphicsConfig(Canvas3D.java:982)
at javax.media.j3d.Canvas3D.<init>(Canvas3D.java:1025)
at SimpleSounds.<init>(SimpleSounds.java:47)
at SimpleSounds.main(SimpleSounds.java:254)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)

Thanks once again

A

itpedersen
Offline
Joined: 2011-02-14
Points: 0

I can se you are using VirtuelUnivers. I dont know so much about that.
But you could try to use SimpelUniverse instead. I cant se why not to use it.
But again remember i am not an expert, just trying to learn the basics.
Hope that we can keep live in java 3d.

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

I have changed the VirtualUuniverse to SimpleUniverse and get the following error message:
run:
Exception in thread "main" javax.media.j3d.SoundException: MediaContainer: setURL - bad URL
at javax.media.j3d.MediaContainerRetained.setURLString(MediaContainerRetained.java:135)
at javax.media.j3d.MediaContainerRetained.setURLString(MediaContainerRetained.java:113)
at javax.media.j3d.MediaContainer.<init>(MediaContainer.java:114)
at SimpleSounds.addObjectSound(SimpleSounds.java:173)
at SimpleSounds.buildContentBranch(SimpleSounds.java:212)
at SimpleSounds.<init>(SimpleSounds.java:240)
at SimpleSounds.main(SimpleSounds.java:258)

but at least the small applet pops up. However it's black and of course no sounds. The error message show it is the URL that is wrong. I presume this is in relation to the sounds i want to play. How can i i play the sound clips that are on my system. The directory works on another program and plays the sound. Just not 3d. Any ideas where i should locate the files in order to play the sound via URL?
Or any ideas as to how to fix the problem/error message above.
Thanks once again
A

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

I've also replaced...
protected Canvas3D myCanvas3D = new Canvas3D(null);

with....
protected Canvas3D myCanvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

so the new code is as follows:
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 javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BackgroundSound;
import javax.media.j3d.BoundingLeaf;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Locale;
import javax.media.j3d.Material;
import javax.media.j3d.MediaContainer;
import javax.media.j3d.PhysicalBody;
import javax.media.j3d.PhysicalEnvironment;
import javax.media.j3d.PointSound;
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 com.sun.j3d.utils.universe.SimpleUniverse;
import java.net.URL;
import javax.vecmath.Color3f;
import javax.vecmath.Point2f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import com.sun.j3d.audioengines.javasound.JavaSoundMixer;
import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
import com.sun.j3d.utils.geometry.Box;
/**
* This application demonstrates the use of 3D sound. It loads three sounds:
* loop3.wav is an ambient background sound and loop1.wav and loop2.wav are
* point sounds. The two point sounds can be switched on and off use AWT
* buttons. The user can navigate around the scene using the keyboard.
*
* @author I.J.Palmer
* @version 1.0
*/
public class SimpleSounds extends Frame implements ActionListener {

//protected Canvas3D myCanvas3D = new Canvas3D(null);
protected Canvas3D myCanvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());

/** The exit button to quit the application */
protected Button exitButton = new Button("Exit");
/** The button to switch on and off the first sound */
protected Button sound1Button = new Button("Sound 1");
/** The button to switch on and off the second sound */
protected Button sound2Button = new Button("Sound 2");
protected BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0,
0.0), 10000.0);
//Create the two point sounds
PointSound sound1 = new PointSound();
PointSound sound2 = new PointSound();
/**
* Build the view branch of the scene graph. In this case a key navigation
* utility object is created and associated with the view transform so that
* the view can be changed via the keyboard.
*
* @return BranchGroup that is the root of the view branch
*/
protected BranchGroup buildViewBranch(Canvas3D c) {
BranchGroup viewBranch = new BranchGroup();
Transform3D viewXfm = new Transform3D();
viewXfm.set(new Vector3f(0.0f, 0.0f, 30.0f));
TransformGroup viewXfmGroup = new TransformGroup(viewXfm);
viewXfmGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
viewXfmGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
ViewPlatform myViewPlatform = new ViewPlatform();
BoundingSphere movingBounds = new BoundingSphere(new Point3d(0.0, 0.0,
0.0), 100.0);
BoundingLeaf boundLeaf = new BoundingLeaf(movingBounds);
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);
KeyNavigatorBehavior keyNav = new KeyNavigatorBehavior(viewXfmGroup);
keyNav.setSchedulingBounds(movingBounds);
viewBranch.addChild(keyNav);
//Create a sounds mixer to use our sounds with
//and initialise it
JavaSoundMixer myMixer = new JavaSoundMixer(myEnvironment);
myMixer.initialize();
return viewBranch;
}
/**
* Add some lights to the scene graph
*
* @param b
* BranchGroup that the lights are added to
*/
protected void addLights(BranchGroup b) {
Color3f ambLightColour = new Color3f(0.5f, 0.5f, 0.5f);
AmbientLight ambLight = new AmbientLight(ambLightColour);
ambLight.setInfluencingBounds(bounds);
Color3f dirLightColour = new Color3f(1.0f, 1.0f, 1.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);
}
/**
* This adds a continuous background sound to the branch group.
*
* @param b
* BranchGroup to add the sound to.
* @param soundFile
* String that is the name of the sound file.
*/
protected void addBackgroundSound(BranchGroup b, String soundFile) {
//Create a media container to load the file
MediaContainer droneContainer = new MediaContainer(soundFile);
//Create the background sound from the media container
BackgroundSound drone = new BackgroundSound(droneContainer, 1.0f);
//Activate the sound
drone.setSchedulingBounds(bounds);
drone.setEnable(true);
//Set the sound to loop forever
drone.setLoop(BackgroundSound.INFINITE_LOOPS);
//Add it to the group
b.addChild(drone);
}
/**
* Add a sound to the transform group. This takes a point sound object and
* loads into it a sounds from a given file. The edge of the sound's extent
* is also defined in a parameter.
*
* @param tg
* TransformGroup that the sound is to be added to
* @param sound
* PointSound to be used
* @param soundFile
* String that is the name of the sound file to be loaded
* @param edge
* float that represents the sound's maximum extent
*/
protected void addObjectSound(TransformGroup tg, PointSound sound,
String soundFile, float edge) {
//First we get the current transform so that we can
//position the sound in the same place
Transform3D objXfm = new Transform3D();
Vector3f objPosition = new Vector3f();
tg.getTransform(objXfm);
objXfm.get(objPosition);
//Create the media container to load the sound
MediaContainer soundContainer = new MediaContainer(soundFile);
//Use the loaded data in the sound
sound.setSoundData(soundContainer);
sound.setInitialGain(1.0f);
//Set the position to that of the given transform
sound.setPosition(new Point3f(objPosition));
//Allow use to switch the sound on and off
sound.setCapability(PointSound.ALLOW_ENABLE_READ);
sound.setCapability(PointSound.ALLOW_ENABLE_WRITE);
sound.setSchedulingBounds(bounds);
//Set it off to start with
sound.setEnable(false);
//Set it to loop forever
sound.setLoop(BackgroundSound.INFINITE_LOOPS);
//Use the edge value to set to extent of the sound
Point2f[] attenuation = { new Point2f(0.0f, 1.0f),
new Point2f(edge, 0.1f) };
sound.setDistanceGain(attenuation);
//Add the sound to the transform group
tg.addChild(sound);
}
protected BranchGroup buildContentBranch() {
//Create the appearance
Appearance app = new Appearance();
Color3f ambientColour = new Color3f(1.0f, 0.0f, 0.0f);
Color3f emissiveColour = new Color3f(0.0f, 0.0f, 0.0f);
Color3f specularColour = new Color3f(1.0f, 1.0f, 1.0f);
Color3f diffuseColour = new Color3f(1.0f, 0.0f, 0.0f);
float shininess = 20.0f;
app.setMaterial(new Material(ambientColour, emissiveColour,
diffuseColour, specularColour, shininess));
//Make the cube
Box myCube = new Box(1.0f, 1.0f, 1.0f, app);
TransformGroup cubeGroup = new TransformGroup();
BranchGroup contentBranch = new BranchGroup();
addLights(contentBranch);
addObjectSound(cubeGroup, sound1, new String("C:/Program Files/Java/jdk1.6.0_21/airplane.wav"), 10.0f);
addObjectSound(cubeGroup, sound2, new String("C:/Program Files/Java/jdk1.6.0_21/footsteps.wav"), 20.0f);
addBackgroundSound(contentBranch, new String("C:/Program Files/Java/jdk1.6.0_21/ding.wav"));
cubeGroup.addChild(myCube);
contentBranch.addChild(cubeGroup);
return contentBranch;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == exitButton) {
dispose();
System.exit(0);
} else if (e.getSource() == sound1Button) {
if (sound1.getEnable())
sound1.setEnable(false);
else
sound1.setEnable(true);
} else if (e.getSource() == sound2Button) {
sound2.setEnable(!sound2.getEnable());
}
}
public SimpleSounds() {
SimpleUniverse myUniverse = new SimpleUniverse();
Locale myLocale = new Locale(myUniverse);
// buildUniverse(myCanvas3D);
myLocale.addBranchGraph(buildContentBranch());
myLocale.addBranchGraph(buildViewBranch(myCanvas3D));
setTitle("SimpleSounds");
setSize(400, 400);
setLayout(new BorderLayout());
Panel bottom = new Panel();
bottom.add(sound1Button);
bottom.add(sound2Button);
bottom.add(exitButton);
add(BorderLayout.CENTER, myCanvas3D);
add(BorderLayout.SOUTH, bottom);
exitButton.addActionListener(this);
sound1Button.addActionListener(this);
sound2Button.addActionListener(this);
setVisible(true);
}
public static void main(String[] args) {
SimpleSounds sw = new SimpleSounds();
}
}