001: /*
002: * SoundBranchGroup.java
003: *
004: * Created on 3 July 2006, 02:01
005: *
006: * To change this template, choose Tools | Template Manager
007: * and open the template in the editor.
008: */
009:
010: package org.jdesktop.j3d.apps.sound;
011:
012: import com.sun.j3d.utils.geometry.Cone;
013: import com.sun.j3d.utils.geometry.Sphere;
014: import javax.media.j3d.Appearance;
015: import javax.media.j3d.BackgroundSound;
016: import javax.media.j3d.BoundingSphere;
017: import javax.media.j3d.Bounds;
018: import javax.media.j3d.BranchGroup;
019: import javax.media.j3d.ConeSound;
020: import javax.media.j3d.Material;
021: import javax.media.j3d.PointSound;
022: import javax.media.j3d.PolygonAttributes;
023: import javax.media.j3d.RenderingAttributes;
024: import javax.media.j3d.Sound;
025: import javax.media.j3d.Transform3D;
026: import javax.media.j3d.TransformGroup;
027: import javax.media.j3d.TransparencyAttributes;
028: import javax.vecmath.*;
029:
030: /**
031: *
032: * @author dave
033: */
034: public class SoundBranchGroup extends BranchGroup {
035:
036: private Sound sound;
037: private SoundBehavior bsb;
038:
039: private RenderingAttributes boundsRenderingAttributes;
040: private RenderingAttributes distanceAttenuationRenderingAttributes;
041: private RenderingAttributes angularAttenuationRenderingAttributes;
042:
043: /** Creates a new instance of SoundBranchGroup */
044: public SoundBranchGroup(Sound sound) {
045: super ();
046: this .sound = sound;
047: setCapability(BranchGroup.ALLOW_DETACH);
048:
049: if (sound instanceof BackgroundSound) {
050: BackgroundSound bgs = (BackgroundSound) sound;
051: initializeBackgroundSound(bgs);
052: } else if (sound instanceof ConeSound) {
053: ConeSound bgs = (ConeSound) sound;
054: initializeConeSound(bgs);
055: } else if (sound instanceof PointSound) {
056: PointSound bgs = (PointSound) sound;
057: initializePointSound(bgs);
058: }
059: }
060:
061: private void initializeConeSound(ConeSound bgs) {
062:
063: //float boundsRadius = 200;
064: //Bounds b = new BoundingSphere(new Point3d(), boundsRadius);
065: //BranchGroup bbg = getBoundingSphereBranchGroup(showBounds, boundsRadius, 1, 0, 0);
066: TransformGroup tg = new TransformGroup();
067: Transform3D t = new Transform3D();
068: //Vector3f v = new Vector3f(x, y, z);
069: //t.setTranslation(v);
070: //tg.addChild(bbg);
071: //addChild(tg);
072:
073: //BranchGroup dgbg = getBoundingSphereBranchGroup(showDistanceAttenuation, distanceAtZero, 0, 0, 1);
074: //tg.addChild(dgbg);
075: BranchGroup bg = getBoundingBranchGroup(bgs);
076: addChild(bg);
077: float distanceAtZero = 0;
078: float radius = 0;
079:
080: if (bgs.getDistanceGainLength() > 0) {
081: float[] ds = new float[bgs.getDistanceGainLength()];
082: float[] as = new float[bgs.getDistanceGainLength()];
083: //Point2f [] pts = new Point2f[bgs.getDistanceGainLength()];
084: bgs.getDistanceGain(ds, as);
085: distanceAtZero = ds[bgs.getDistanceGainLength() - 1];
086: }
087: if (bgs.getAngularAttenuationLength() > 0) {
088: float[] f0 = new float[bgs.getAngularAttenuationLength()];
089: float[] f1 = new float[bgs.getAngularAttenuationLength()];
090: float[] f2 = new float[bgs.getAngularAttenuationLength()];
091: //Point2f [] pts = new Point2f[bgs.getDistanceGainLength()];
092: bgs.getAngularAttenuation(f0, f1, f2);
093: radius = (float) (distanceAtZero * Math.tan(f0[0]));
094: TransformGroup aatg = new TransformGroup();
095: Transform3D aatTranslation = new Transform3D();
096: Transform3D aatRotation = new Transform3D();
097: Vector3f aav = new Vector3f(0, 0, distanceAtZero / 2);
098: aatTranslation.setTranslation(aav);
099: aatRotation.rotX(-Math.PI / 2);
100: aatTranslation.mul(aatRotation);
101: aatg.setTransform(aatTranslation);
102: //bg.addChild(aatg);
103:
104: BranchGroup abg = getAngularAttenuationConeBranchGroup(
105: radius, distanceAtZero);
106: aatg.addChild(abg);
107: addChild(aatg);
108:
109: if (bgs.getDistanceGainLength() > 0) {
110: //BranchGroup dbg = getSphereBranchGroup(distanceAtZero, false);
111: //addChild(dbg);
112: }
113: }
114:
115: addChild(bgs);
116: bsb = new SoundBehavior(bgs, boundsRenderingAttributes,
117: distanceAttenuationRenderingAttributes);
118: addChild(bsb);
119: }
120:
121: private void initializePointSound(PointSound bgs) {
122:
123: //float boundsRadius = 200;
124: //Bounds b = new BoundingSphere(new Point3d(), boundsRadius);
125: //BranchGroup bbg = getBoundingSphereBranchGroup(showBounds, boundsRadius, 1, 0, 0);
126:
127: //tg.addChild(bbg);
128: //addChild(tg);
129:
130: //BranchGroup dgbg = getBoundingSphereBranchGroup(showDistanceAttenuation, distanceAtZero, 0, 0, 1);
131: //tg.addChild(dgbg);
132: Point3f position = new Point3f();
133: bgs.getPosition(position);
134:
135: Transform3D t = new Transform3D();
136: Vector3f v = new Vector3f(position.x, position.y, position.z);
137: t.setTranslation(v);
138: TransformGroup tg = new TransformGroup(t);
139: BranchGroup bg = getBoundingBranchGroup(bgs);
140: tg.addChild(bg);
141: //addChild(bg);
142:
143: if (bgs.getDistanceGainLength() > 0) {
144: float[] ds = new float[bgs.getDistanceGainLength()];
145: float[] as = new float[bgs.getDistanceGainLength()];
146: //Point2f [] pts = new Point2f[bgs.getDistanceGainLength()];
147: bgs.getDistanceGain(ds, as);
148: float distanceAtZero = ds[bgs.getDistanceGainLength() - 1];
149:
150: BranchGroup dbg = getSphereBranchGroup(distanceAtZero,
151: false);
152: tg.addChild(dbg);
153: addChild(tg);
154: }
155:
156: addChild(bgs);
157: bsb = new SoundBehavior(bgs, boundsRenderingAttributes,
158: distanceAttenuationRenderingAttributes);
159: addChild(bsb);
160: }
161:
162: private void initializeBackgroundSound(BackgroundSound bgs) {
163: BranchGroup bbg = getBoundingBranchGroup(bgs);
164:
165: //Bounds b = new BoundingSphere(new Point3d(), 10);
166: //BranchGroup bbg = getBoundingSphereBranchGroup(true, 10.0f, 1, 0, 0);
167: addChild(bbg);
168: addChild(bgs);
169: bsb = new SoundBehavior(bgs, boundsRenderingAttributes);
170: addChild(bsb);
171: }
172:
173: private BranchGroup getBoundingBranchGroup(Sound sound) {
174: double radius = 10;
175: Bounds bounds = sound.getSchedulingBounds();
176: if (bounds != null) {
177: if (bounds instanceof BoundingSphere) {
178: BoundingSphere bs = (BoundingSphere) bounds;
179: radius = bs.getRadius();
180: }
181: }
182: return getSphereBranchGroup((float) radius, true);
183: }
184:
185: public BranchGroup getAngularAttenuationConeBranchGroup(
186: float radius, float height) {
187: BranchGroup bg = new BranchGroup();
188: Appearance a = new Appearance();
189: TransparencyAttributes ta = new TransparencyAttributes();
190: ta.setTransparency(0.5f);
191: a.setTransparencyAttributes(ta);
192: Material m = new Material();
193: m.setDiffuseColor(0, 0, 1);
194: m.setAmbientColor(0, 0, 1);
195: m.setShininess(8);
196: a.setMaterial(m);
197: angularAttenuationRenderingAttributes = new RenderingAttributes();
198: a.setRenderingAttributes(angularAttenuationRenderingAttributes);
199: PolygonAttributes pa = new PolygonAttributes();
200: pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
201: pa.setCullFace(PolygonAttributes.CULL_NONE);
202: a.setPolygonAttributes(pa);
203: Cone s = new Cone(radius, height, a);
204: bg.addChild(s);
205: return bg;
206: }
207:
208: private BranchGroup getSphereBranchGroup(float radius,
209: boolean isBounds) {
210: BranchGroup bbg = new BranchGroup();
211: Appearance a = new Appearance();
212: TransparencyAttributes ta = new TransparencyAttributes();
213: ta.setTransparency(0.5f);
214: a.setTransparencyAttributes(ta);
215: if (isBounds) {
216: Material m = new Material();
217: m.setDiffuseColor(1, 0, 0);
218: m.setAmbientColor(1, 0, 0);
219: m.setShininess(8);
220: a.setMaterial(m);
221: boundsRenderingAttributes = new RenderingAttributes();
222: boundsRenderingAttributes
223: .setCapability(RenderingAttributes.ALLOW_VISIBLE_READ);
224: boundsRenderingAttributes
225: .setCapability(RenderingAttributes.ALLOW_VISIBLE_WRITE);
226: a.setRenderingAttributes(boundsRenderingAttributes);
227: } else {
228: Material m = new Material();
229: m.setDiffuseColor(0, 1, 0);
230: m.setAmbientColor(0, 1, 0);
231: m.setShininess(8);
232: a.setMaterial(m);
233: distanceAttenuationRenderingAttributes = new RenderingAttributes();
234: distanceAttenuationRenderingAttributes
235: .setCapability(RenderingAttributes.ALLOW_VISIBLE_READ);
236: distanceAttenuationRenderingAttributes
237: .setCapability(RenderingAttributes.ALLOW_VISIBLE_WRITE);
238: a
239: .setRenderingAttributes(distanceAttenuationRenderingAttributes);
240: }
241: PolygonAttributes pa = new PolygonAttributes();
242: pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
243: pa.setCullFace(PolygonAttributes.CULL_NONE);
244: a.setPolygonAttributes(pa);
245: Sphere s = new Sphere(radius, a);
246: bbg.addChild(s);
247: return bbg;
248: }
249:
250: public void setBoundsVisible(boolean isBoundsVisible) {
251: bsb.setBoundsVisible(isBoundsVisible);
252: }
253:
254: public void setDistanceAttenuationVisible(
255: boolean isDistanceAttenuationVisible) {
256: bsb.setDistanceAttenuationVisible(isDistanceAttenuationVisible);
257: }
258:
259: public void setAngularAttenuationVisible(
260: boolean isAngularAttenuationVisible) {
261: bsb.setAngularAttenuationVisible(isAngularAttenuationVisible);
262: }
263: }
|