javax.media.j3d.SoundscapeRetained Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java3d-core Show documentation
Show all versions of java3d-core Show documentation
Java3D Core And Java3D Util Libraries
The newest version!
/*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package javax.media.j3d;
import java.util.ArrayList;
/**
* The SoundscapeRetained object defines all soundscape rendering state
* as a subclass of a Leaf node.
*/
class SoundscapeRetained extends LeafRetained
{
static final int ATTRIBUTES_CHANGED = 0x00001;
static final int BOUNDING_LEAF_CHANGED = 0x00002;
static final int APPLICATION_BOUNDS_CHANGED = 0x00004;
/**
* Soundscape nodes application region
*/
Bounds applicationRegion = null;
/**
* The bounding leaf reference
*/
BoundingLeafRetained boundingLeaf = null;
/**
* The transformed Application Region
*/
Bounds transformedRegion = null;
/**
* Aural attributes associated with this Soundscape
*/
AuralAttributesRetained attributes = null;
// A bitmask that indicates that the something has changed.
int isDirty = 0xffff;
// Target threads to be notified when sound changes
int targetThreads = J3dThread.UPDATE_SOUND |
J3dThread.SOUND_SCHEDULER;
// Is true, if the mirror light is viewScoped
boolean isViewScoped = false;
void dispatchMessage(int dirtyBit, Object argument) {
// Send message including a integer argument
J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.SOUNDSCAPE_CHANGED;
createMessage.universe = universe;
createMessage.args[0] = this;
createMessage.args[1]= new Integer(dirtyBit);
createMessage.args[2] = new Integer(0);
createMessage.args[3] = null;
createMessage.args[4] = argument;
VirtualUniverse.mc.processMessage(createMessage);
}
SoundscapeRetained() {
super();
this.nodeType = NodeRetained.SOUNDSCAPE;
localBounds = new BoundingBox((Bounds)null);
}
/**
* Set the Soundscape's application region.
* @param region a region that contains the Soundscape's new application region
*/
void setApplicationBounds(Bounds region)
{
if (region != null) {
applicationRegion = (Bounds) region.clone();
if (staticTransform != null) {
applicationRegion.transform(staticTransform.transform);
}
}
else {
applicationRegion = null;
}
updateTransformChange();
this.isDirty |= APPLICATION_BOUNDS_CHANGED;
dispatchMessage(APPLICATION_BOUNDS_CHANGED, region);
if (source != null && source.isLive()) {
notifySceneGraphChanged(false);
}
}
/**
* Get the Soundscape's application region.
* @return this Soundscape's application region information
*/
Bounds getApplicationBounds()
{
Bounds b = null;
if (this.applicationRegion == null)
return (Bounds)null;
else {
b = (Bounds) applicationRegion.clone();
if (staticTransform != null) {
Transform3D invTransform = staticTransform.getInvTransform();
b.transform(invTransform);
}
return b;
}
}
/**
* Set the Soundscape's application region to the specified Leaf node.
*/
void setApplicationBoundingLeaf(BoundingLeaf region) {
if (boundingLeaf != null) {
// Remove the soundscape as users of the original bounding leaf
boundingLeaf.mirrorBoundingLeaf.removeUser(this);
}
if (region != null) {
boundingLeaf = (BoundingLeafRetained)region.retained;
boundingLeaf.mirrorBoundingLeaf.addUser(this);
} else {
boundingLeaf = null;
}
updateTransformChange();
this.isDirty |= BOUNDING_LEAF_CHANGED;
dispatchMessage(BOUNDING_LEAF_CHANGED, region);
// QUESTION needed??
if (source != null && source.isLive()) {
notifySceneGraphChanged(false);
}
}
/**
* Get the Soundscape's application region
*/
BoundingLeaf getApplicationBoundingLeaf() {
if (boundingLeaf != null) {
return (BoundingLeaf)boundingLeaf.source;
} else {
return (BoundingLeaf)null;
}
}
/**
* Set a set of aural attributes for this Soundscape
* @param attributes aural attributes to be set
*/
void setAuralAttributes(AuralAttributes attributes)
{
if (this.source.isLive()) {
if (this.attributes != null) {
this.attributes.clearLive(refCount);
}
if (attributes != null) {
((AuralAttributesRetained)attributes.retained).setLive(inBackgroundGroup, refCount);
}
}
if (this.attributes != null) {
this.attributes.removeUser(this);
}
if (attributes != null) {
this.attributes = (AuralAttributesRetained)attributes.retained;
this.attributes.addUser(this);
} else {
this.attributes = null;
}
// copy all fields out of attributes and put into our copy of attributes
this.isDirty |= ATTRIBUTES_CHANGED;
dispatchMessage(ATTRIBUTES_CHANGED, attributes);
if (source != null && source.isLive()) {
notifySceneGraphChanged(false);
}
}
/**
* Retrieve a reference to Aural Attributes
* @return attributes aural attributes to be returned
*/
AuralAttributes getAuralAttributes()
{
if (attributes != null) {
return ((AuralAttributes) attributes.source);
}
else
return ((AuralAttributes) null);
}
/*
// NOTE: OLD CODE
// The update Object function.
public synchronized void updateObject() {
if ((attributes != null) && (attributes.aaDirty)) {
if (attributes.mirrorAa == null) {
attributes.mirrorAa = new AuralAttributesRetained();
}
attributes.mirrorAa.update(attributes);
}
}
*/
// The update Object function.
@Override
synchronized void updateMirrorObject(Object[] objs) {
// NOTE: There doesn't seem to be a use for mirror objects since
// Soundscapes can't be shared.
// This method updates the transformed region from either bounding
// leaf or application bounds. Bounding leaf takes precidence.
Transform3D trans = null;
int component = ((Integer)objs[1]).intValue();
if ((component & BOUNDING_LEAF_CHANGED) != 0) {
if (this.boundingLeaf != null) {
transformedRegion = boundingLeaf.transformedRegion;
}
else { // evaluate Application Region if not null
if (applicationRegion != null) {
transformedRegion = (Bounds)applicationRegion.clone();
transformedRegion.transform(applicationRegion,
getLastLocalToVworld());
}
else {
transformedRegion = null;
}
}
}
else if ((component & APPLICATION_BOUNDS_CHANGED) != 0) {
// application bounds only used when bounding leaf null
if (boundingLeaf == null) {
transformedRegion = (Bounds)applicationRegion.clone();
transformedRegion.transform(applicationRegion,
getLastLocalToVworld());
}
else {
transformedRegion = null;
}
}
}
// The update tranform fields
@Override
synchronized void updateTransformChange() {
if (boundingLeaf != null) {
transformedRegion = boundingLeaf.transformedRegion;
}
else { // evaluate Application Region if not null
if (applicationRegion != null) {
transformedRegion = applicationRegion.copy(transformedRegion);
transformedRegion.transform(applicationRegion,
getLastLocalToVworld());
}
else {
transformedRegion = null;
}
}
}
void updateBoundingLeaf(long refTime) {
// This is necessary, if for example, the region
// changes from sphere to box.
if (boundingLeaf != null && boundingLeaf.switchState.currentSwitchOn) {
transformedRegion = boundingLeaf.transformedRegion;
} else { // evaluate Application Region if not null
if (applicationRegion != null) {
transformedRegion = applicationRegion.copy(transformedRegion);
transformedRegion.transform(applicationRegion,
getLastLocalToVworld());
} else {
transformedRegion = null;
}
}
}
// QUESTION: not needed?
/*
synchronized void initMirrorObject(SoundscapeRetained ms) {
GroupRetained group;
Transform3D trans;
Bounds region = null;
if (ms == null)
return;
}
ms.isDirty = isDirty;
ms.setApplicationBounds(getApplicationBounds());
ms.setApplicationBoundingLeaf(getApplicationBoundingLeaf());
ms.setAuralAttributes(getAuralAttributes());
// QUESTION: no lineage of mirror node kept??
ms.sgSound = sgSound;
ms.key = null;
ms.mirrorSounds = new SoundscapeRetained[1];
ms.numMirrorSounds = 0;
ms.parent = parent;
ms.transformedRegion = null;
if (boundingLeaf != null) {
if (ms.boundingLeaf != null)
ms.boundingLeaf.removeUser(ms);
ms.boundingLeaf = boundingLeaf.mirrorBoundingLeaf;
// Add this mirror object as user
ms.boundingLeaf.addUser(ms);
ms.transformedRegion = ms.boundingLeaf.transformedRegion;
}
else {
ms.boundingLeaf = null;
}
if (applicationRegion != null) {
ms.applicationRegion = (Bounds) applicationRegion.clone();
// Assign region only if bounding leaf is null
if (ms.transformedRegion == null) {
ms.transformedRegion = (Bounds) ms.applicationRegion.clone();
ms.transformedRegion.transform(ms.applicationRegion,
ms.getLastLocalToVworld());
}
}
else {
ms.applicationRegion = null;
}
}
*/
/**
* This setLive routine first calls the superclass's method, then
* it adds itself to the list of soundscapes
*/
@Override
void setLive(SetLiveState s) {
super.doSetLive(s);
if (attributes != null) {
attributes.setLive(inBackgroundGroup, s.refCount);
}
if (s.transformTargets != null && s.transformTargets[0] != null) {
s.transformTargets[0].addNode(this, Targets.SND_TARGETS);
s.notifyThreads |= J3dThread.UPDATE_TRANSFORM;
}
// If its view Scoped, then add this list
// to be sent to Sound Structure
if ((s.viewScopedNodeList != null) && (s.viewLists != null)) {
s.viewScopedNodeList.add(this);
s.scopedNodesViewList.add(s.viewLists.get(0));
} else {
s.nodeList.add(this);
}
if (inBackgroundGroup) {
throw new
IllegalSceneGraphException(J3dI18N.getString("SoundscapeRetained1"));
}
if (inSharedGroup) {
throw new
IllegalSharingException(J3dI18N.getString("SoundscapeRetained0"));
}
// process switch leaf
if (s.switchTargets != null &&
s.switchTargets[0] != null) {
s.switchTargets[0].addNode(this, Targets.SND_TARGETS);
}
switchState = s.switchStates.get(0);
s.notifyThreads |= (J3dThread.UPDATE_SOUND |
J3dThread.SOUND_SCHEDULER);
super.markAsLive();
}
/**
* This clearLive routine first calls the superclass's method, then
* it removes itself to the list of lights
*/
@Override
void clearLive(SetLiveState s) {
super.clearLive(s);
if (s.switchTargets != null &&
s.switchTargets[0] != null) {
s.switchTargets[0].addNode(this, Targets.SND_TARGETS);
}
if (attributes != null) {
attributes.clearLive(s.refCount);
}
if (s.transformTargets != null && s.transformTargets[0] != null) {
s.transformTargets[0].addNode(this, Targets.SND_TARGETS);
s.notifyThreads |= J3dThread.UPDATE_TRANSFORM;
}
// If its view Scoped, then add this list
// to be sent to Sound Structure
if ((s.viewScopedNodeList != null) && (s.viewLists != null)) {
s.viewScopedNodeList.add(this);
s.scopedNodesViewList.add(s.viewLists.get(0));
} else {
s.nodeList.add(this);
}
s.notifyThreads |= (J3dThread.UPDATE_SOUND |
J3dThread.SOUND_SCHEDULER);
}
// Simply pass along to the NodeComponents
/*
void compile(CompileState compState) {
setCompiled();
if (attributes != null)
attributes.compile(compState);
}
*/
// This makes this sound look just like the one passed in
void update(SoundscapeRetained ss) {
applicationRegion = (Bounds)ss.applicationRegion.clone();
attributes = ss.attributes;
}
@Override
void mergeTransform(TransformGroupRetained xform) {
super.mergeTransform(xform);
if (applicationRegion != null) {
applicationRegion.transform(xform.transform);
}
}
@Override
void getMirrorObjects(ArrayList leafList, HashKey key) {
leafList.add(this);
}
}