Skip to content

Commit 3cc16ab

Browse files
authored
Merge pull request #2432 from capdevon/capdevon-TestAudioDirectional
jme3-examples: add TestAudioDirectional class
2 parents 86055ea + 18063ee commit 3cc16ab

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package jme3test.audio;
2+
3+
import com.jme3.app.SimpleApplication;
4+
import com.jme3.audio.AudioData;
5+
import com.jme3.audio.AudioNode;
6+
import com.jme3.environment.util.BoundingSphereDebug;
7+
import com.jme3.input.KeyInput;
8+
import com.jme3.input.controls.ActionListener;
9+
import com.jme3.input.controls.KeyTrigger;
10+
import com.jme3.input.controls.Trigger;
11+
import com.jme3.material.Material;
12+
import com.jme3.math.ColorRGBA;
13+
import com.jme3.math.FastMath;
14+
import com.jme3.math.Vector3f;
15+
import com.jme3.scene.Geometry;
16+
import com.jme3.scene.Mesh;
17+
import com.jme3.scene.Node;
18+
import com.jme3.scene.Spatial;
19+
import com.jme3.scene.debug.Arrow;
20+
import com.jme3.scene.debug.Grid;
21+
import com.jme3.scene.shape.Line;
22+
23+
/**
24+
* @author capdevon
25+
*/
26+
public class TestAudioDirectional extends SimpleApplication implements ActionListener {
27+
28+
public static void main(String[] args) {
29+
TestAudioDirectional app = new TestAudioDirectional();
30+
app.start();
31+
}
32+
33+
private AudioNode audioSource;
34+
private final Vector3f tempDirection = new Vector3f();
35+
private boolean rotationEnabled = true;
36+
37+
@Override
38+
public void simpleInitApp() {
39+
configureCamera();
40+
41+
audioSource = new AudioNode(assetManager,
42+
"Sound/Environment/Ocean Waves.ogg", AudioData.DataType.Buffer);
43+
audioSource.setLooping(true);
44+
audioSource.setPositional(true);
45+
audioSource.setMaxDistance(100);
46+
audioSource.setRefDistance(5);
47+
audioSource.setDirectional(true);
48+
// audioSource.setOuterGain(0.2f); // Volume outside the cone is 20% of the inner volume (Not Supported by jME)
49+
audioSource.setInnerAngle(30); // 30-degree cone (15 degrees on each side of the direction)
50+
audioSource.setOuterAngle(90); // 90-degree cone (45 degrees on each side of the direction)
51+
audioSource.play();
52+
53+
// just a green sphere to mark the spot
54+
Geometry sphere = BoundingSphereDebug.createDebugSphere(assetManager);
55+
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
56+
mat.setColor("Color", ColorRGBA.Green);
57+
sphere.setMaterial(mat);
58+
sphere.setLocalScale(0.5f);
59+
audioSource.attachChild(sphere);
60+
61+
float angleIn = audioSource.getInnerAngle() * FastMath.DEG_TO_RAD;
62+
float angleOut = audioSource.getOuterAngle() * FastMath.DEG_TO_RAD;
63+
Vector3f forwardDir = audioSource.getWorldRotation().mult(Vector3f.UNIT_Z);
64+
65+
audioSource.attachChild(createFOV(angleIn, 20f));
66+
audioSource.attachChild(createFOV(angleOut, 20f));
67+
audioSource.attachChild(makeShape("ZAxis", new Arrow(forwardDir.mult(5)), ColorRGBA.Blue));
68+
rootNode.attachChild(audioSource);
69+
70+
Geometry grid = makeShape("DebugGrid", new Grid(21, 21, 2), ColorRGBA.Gray);
71+
grid.center().move(0, 0, 0);
72+
rootNode.attachChild(grid);
73+
74+
registerInputMappings();
75+
}
76+
77+
@Override
78+
public void simpleUpdate(float tpf) {
79+
if (rotationEnabled) {
80+
// Example: Rotate the audio node
81+
audioSource.rotate(0, tpf * 0.5f, 0);
82+
audioSource.setDirection(audioSource.getWorldRotation().mult(Vector3f.UNIT_Z, tempDirection));
83+
}
84+
}
85+
86+
@Override
87+
public void onAction(String name, boolean isPressed, float tpf) {
88+
if (!isPressed) return;
89+
90+
if (name.equals("toggleDirectional")) {
91+
boolean directional = !audioSource.isDirectional();
92+
audioSource.setDirectional(directional);
93+
System.out.println("directional: " + directional);
94+
95+
} else if (name.equals("toggleRotationEnabled")) {
96+
rotationEnabled = !rotationEnabled;
97+
System.out.println("rotationEnabled: " + rotationEnabled);
98+
}
99+
}
100+
101+
private void registerInputMappings() {
102+
addMapping("toggleDirectional", new KeyTrigger(KeyInput.KEY_SPACE));
103+
addMapping("toggleRotationEnabled", new KeyTrigger(KeyInput.KEY_P));
104+
}
105+
106+
private void addMapping(String mappingName, Trigger... triggers) {
107+
inputManager.addMapping(mappingName, triggers);
108+
inputManager.addListener(this, mappingName);
109+
}
110+
111+
private void configureCamera() {
112+
flyCam.setMoveSpeed(25f);
113+
flyCam.setDragToRotate(true);
114+
115+
cam.setLocation(new Vector3f(12, 5, 12));
116+
cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
117+
}
118+
119+
private Geometry makeShape(String name, Mesh mesh, ColorRGBA color) {
120+
Geometry geo = new Geometry(name, mesh);
121+
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
122+
mat.setColor("Color", color);
123+
geo.setMaterial(mat);
124+
return geo;
125+
}
126+
127+
private Spatial createFOV(float angleRad, float extent) {
128+
Vector3f origin = new Vector3f();
129+
Node node = new Node("Cone");
130+
Vector3f sx = dirFromAngle(angleRad/2).scaleAdd(extent, origin);
131+
Vector3f dx = dirFromAngle(-angleRad/2).scaleAdd(extent, origin);
132+
node.attachChild(makeShape("Line.SX", new Line(origin, sx), ColorRGBA.Red));
133+
node.attachChild(makeShape("Line.DX", new Line(origin, dx), ColorRGBA.Red));
134+
135+
return node;
136+
}
137+
138+
private Vector3f dirFromAngle(float angleRad) {
139+
return new Vector3f(FastMath.sin(angleRad), 0, FastMath.cos(angleRad));
140+
}
141+
}

0 commit comments

Comments
 (0)