javax.media.j3d.AlternateAppearanceRetained Maven / Gradle / Ivy
Show all versions of java3d-core Show documentation
/*
* Copyright 1999-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;
import java.util.Enumeration;
import java.util.Vector;
class AlternateAppearanceRetained extends LeafRetained {
// Statics used when something in the alternate app changes
static final int APPEARANCE_CHANGED = 0x0001;
static final int SCOPE_CHANGED = 0x0002;
static final int BOUNDS_CHANGED = 0x0004;
static final int BOUNDINGLEAF_CHANGED = 0x0008;
static final int INIT_MIRROR = 0x0010; // setLive
static final int CLEAR_MIRROR = 0x0020; // clearLive
/**
* The Boundary object defining the lights's region of influence.
*/
Bounds regionOfInfluence = null;
/**
* The bounding leaf reference
*/
BoundingLeafRetained boundingLeaf = null;
/**
* Vector of GroupRetained nodes that scopes this alternate app .
*/
Vector scopes = new Vector();
// This is true when this alternate app is referenced in an immediate mode context
boolean inImmCtx = false;
// Target threads to be notified when light changes
static final int targetThreads = J3dThread.UPDATE_RENDERING_ENVIRONMENT |
J3dThread.UPDATE_RENDER;
// Boolean to indicate if this object is scoped (only used for mirror objects
boolean isScoped = false;
// The object that contains the dynamic HashKey - a string type object
// Used in scoping
HashKey tempKey = new HashKey(250);
/**
* The transformed value of the applicationRegion.
*/
Bounds region = null;
/**
* mirror Alternate appearance
*/
AlternateAppearanceRetained mirrorAltApp = null;
/**
* Appearance for this object
*/
AppearanceRetained appearance;
/**
* A reference to the scene graph alternateApp
*/
AlternateAppearanceRetained sgAltApp = null;
/**
* Is true, if the mirror altapp is viewScoped
*/
boolean isViewScoped = false;
AlternateAppearanceRetained() {
this.nodeType = NodeRetained.ALTERNATEAPPEARANCE;
localBounds = new BoundingBox((Bounds)null);
}
/**
* Initializes the appearance
*/
void initAppearance(Appearance app) {
if (app != null)
appearance = (AppearanceRetained) app.retained;
else
appearance = null;
}
/**
* sets the appearance and send a message
*/
void setAppearance(Appearance app) {
if (appearance != null)
synchronized(appearance.liveStateLock) {
appearance.clearLive(refCount);
}
initAppearance(app);
if (appearance != null) {
synchronized(appearance.liveStateLock) {
appearance.setLive(inBackgroundGroup, refCount);
}
}
// There is no need to clone the appearance's mirror
sendMessage(APPEARANCE_CHANGED,
(appearance != null ? appearance.mirror: null));
}
Appearance getAppearance() {
return (appearance == null ? null: (Appearance) appearance.source);
}
/**
* Set the alternate's region of influence.
*/
void initInfluencingBounds(Bounds region) {
if (region != null) {
this.regionOfInfluence = (Bounds) region.clone();
} else {
this.regionOfInfluence = null;
}
}
/**
* Set the alternate's region of influence and send message
*/
void setInfluencingBounds(Bounds region) {
initInfluencingBounds(region);
sendMessage(BOUNDS_CHANGED,
(region != null ? region.clone() : null));
}
/**
* Get the alternate's region of Influence.
*/
Bounds getInfluencingBounds() {
return (regionOfInfluence != null ?
(Bounds) regionOfInfluence.clone() : null);
}
/**
* Set the alternate's region of influence to the specified Leaf node.
*/
void initInfluencingBoundingLeaf(BoundingLeaf region) {
if (region != null) {
boundingLeaf = (BoundingLeafRetained)region.retained;
} else {
boundingLeaf = null;
}
}
/**
* Set the alternate's region of influence to the specified Leaf node.
*/
void setInfluencingBoundingLeaf(BoundingLeaf region) {
if (boundingLeaf != null)
boundingLeaf.mirrorBoundingLeaf.removeUser(mirrorAltApp);
if (region != null) {
boundingLeaf = (BoundingLeafRetained)region.retained;
boundingLeaf.mirrorBoundingLeaf.addUser(mirrorAltApp);
} else {
boundingLeaf = null;
}
sendMessage(BOUNDINGLEAF_CHANGED,
(boundingLeaf != null ?
boundingLeaf.mirrorBoundingLeaf : null));
}
/**
* Get the alternate's region of influence.
*/
BoundingLeaf getInfluencingBoundingLeaf() {
return (boundingLeaf != null ?
(BoundingLeaf)boundingLeaf.source : null);
}
/**
* Replaces the specified scope with the scope provided.
* @param scope the new scope
* @param index which scope to replace
*/
void initScope(Group scope, int index) {
scopes.setElementAt((GroupRetained)(scope.retained), index);
}
/**
* Replaces the specified scope with the scope provided.
* @param scope the new scope
* @param index which scope to replace
*/
void setScope(Group scope, int index) {
ArrayList removeScopeList = new ArrayList();
ArrayList addScopeList = new ArrayList();
Object[] scopeInfo = new Object[3];
GroupRetained group = scopes.get(index);
tempKey.reset();
group.removeAllNodesForScopedAltApp(mirrorAltApp, removeScopeList, tempKey);
group = (GroupRetained)scope.retained;
initScope(scope, index);
tempKey.reset();
// If its a group, then add the scope to the group, if
// its a shape, then keep a list to be added during
// updateMirrorObject
group.addAllNodesForScopedAltApp(mirrorAltApp,addScopeList, tempKey);
scopeInfo[0] = addScopeList;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE:Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
Group getScope(int index) {
return (Group)scopes.elementAt(index).source;
}
/**
* Inserts the specified scope at specified index.before the
* alt app is live
* @param scope the new scope
* @param index position to insert new scope at
*/
void initInsertScope(Node scope, int index) {
GroupRetained group = (GroupRetained)scope.retained;
scopes.insertElementAt(group, index);
group.setAltAppScope();
}
/**
* Inserts the specified scope at specified index and sends
* a message
* @param scope the new scope
* @param index position to insert new scope at
*/
void insertScope(Node scope, int index) {
Object[] scopeInfo = new Object[3];
ArrayList addScopeList = new ArrayList();
GroupRetained group = (GroupRetained)scope.retained;
initInsertScope(scope, index);
group = (GroupRetained)scope.retained;
tempKey.reset();
group.addAllNodesForScopedAltApp(mirrorAltApp,addScopeList, tempKey);
scopeInfo[0] = addScopeList;
scopeInfo[1] = null;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
void initRemoveScope(int index) {
GroupRetained group = scopes.remove(index);
group.removeAltAppScope();
}
void removeScope(int index) {
Object[] scopeInfo = new Object[3];
ArrayList removeScopeList = new ArrayList();
GroupRetained group = scopes.elementAt(index);
tempKey.reset();
group.removeAllNodesForScopedAltApp(mirrorAltApp, removeScopeList, tempKey);
initRemoveScope(index);
scopeInfo[0] = null;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
/**
* Removes the specified Group node from this node's list of scopes.
* Method is a no-op if the
* specified node is not found
* @param The Group node to be removed
*/
void removeScope(Group scope) {
int ind = indexOfScope(scope);
if(ind >= 0)
removeScope(ind);
}
void initRemoveScope(Group scope) {
int ind = indexOfScope(scope);
if(ind >= 0)
initRemoveScope(ind);
}
void removeAllScopes() {
ArrayList removeScopeList = new ArrayList();
int n = scopes.size();
for(int index = n-1; index >= 0; index--) {
GroupRetained group = scopes.elementAt(index);
tempKey.reset();
group.removeAllNodesForScopedAltApp(mirrorAltApp, removeScopeList, tempKey);
initRemoveScope(index);
}
Object[] scopeInfo = new Object[3];
scopeInfo[0] = null;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
void initRemoveAllScopes() {
int n = scopes.size();
for(int i = n-1; i >= 0; i--)
initRemoveScope(i);
}
/**
* Returns an enumeration object of the scoperen.
* @return an enumeration object of the scoperen
*/
Enumeration getAllScopes() {
Enumeration elm = scopes.elements();
Vector v = new Vector(scopes.size());
while (elm.hasMoreElements()) {
v.add((Group)elm.nextElement().source);
}
return v.elements();
}
/**
* Returns the index of the specified Group node in this node's list of scopes.
* @param scope the Group node whose index is needed
*/
int indexOfScope(Group scope) {
if(scope != null)
return scopes.indexOf(scope.retained);
else
return scopes.indexOf(null);
}
/**
* Appends the specified scope to this node's list of scopes before
* the alt app is alive
* @param scope the scope to add to this node's list of scopes
*/
void initAddScope(Group scope) {
GroupRetained group = (GroupRetained)scope.retained;
scopes.addElement(group);
group.setAltAppScope();
}
/**
* Appends the specified scope to this node's list of scopes.
* @param scope the scope to add to this node's list of scopes
*/
void addScope(Group scope) {
Object[] scopeInfo = new Object[3];
ArrayList addScopeList = new ArrayList();
GroupRetained group = (GroupRetained)scope.retained;
initAddScope(scope);
tempKey.reset();
group.addAllNodesForScopedAltApp(mirrorAltApp,addScopeList, tempKey);
scopeInfo[0] = addScopeList;
scopeInfo[1] = null;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
sendMessage(SCOPE_CHANGED, scopeInfo);
}
/**
* Returns a count of this nodes' scopes.
* @return the number of scopes descendant from this node
*/
int numScopes() {
return scopes.size();
}
/**
* This sets the immedate mode context flag
*/
void setInImmCtx(boolean inCtx) {
inImmCtx = inCtx;
}
/**
* This gets the immedate mode context flag
*/
boolean getInImmCtx() {
return (inImmCtx);
}
boolean isScoped() {
return (scopes != null);
}
void updateImmediateMirrorObject(Object[] objs) {
int component = ((Integer)objs[1]).intValue();
if ((component & APPEARANCE_CHANGED) != 0) {
mirrorAltApp.appearance = (AppearanceRetained)objs[2];
}
if ((component & BOUNDS_CHANGED) != 0) {
mirrorAltApp.regionOfInfluence = (Bounds) objs[2];
if (mirrorAltApp.boundingLeaf == null) {
if (objs[2] != null) {
mirrorAltApp.region = mirrorAltApp.regionOfInfluence.copy(mirrorAltApp.region);
mirrorAltApp.region.transform(
mirrorAltApp.regionOfInfluence,
getCurrentLocalToVworld());
}
else {
mirrorAltApp.region = null;
}
}
}
else if ((component & BOUNDINGLEAF_CHANGED) != 0) {
mirrorAltApp.boundingLeaf = (BoundingLeafRetained)objs[2];
if (objs[2] != null) {
mirrorAltApp.region = mirrorAltApp.boundingLeaf.transformedRegion;
}
else {
if (mirrorAltApp.regionOfInfluence != null) {
mirrorAltApp.region = mirrorAltApp.regionOfInfluence.copy(mirrorAltApp.region);
mirrorAltApp.region.transform(
mirrorAltApp.regionOfInfluence,
getCurrentLocalToVworld());
}
else {
mirrorAltApp.region = null;
}
}
}
else if ((component & SCOPE_CHANGED) != 0) {
Object[] scopeList = (Object[])objs[2];
ArrayList addList = (ArrayList)scopeList[0];
ArrayList removeList = (ArrayList)scopeList[1];
boolean isScoped = ((Boolean)scopeList[2]).booleanValue();
if (addList != null) {
mirrorAltApp.isScoped = isScoped;
for (int i = 0; i < addList.size(); i++) {
Shape3DRetained obj = ((GeometryAtom)addList.get(i)).source;
obj.addAltApp(mirrorAltApp);
}
}
if (removeList != null) {
mirrorAltApp.isScoped = isScoped;
for (int i = 0; i < removeList.size(); i++) {
Shape3DRetained obj = ((GeometryAtom)removeList.get(i)).source;
obj.removeAltApp(mirrorAltApp);
}
}
}
}
/** Note: This routine will only be called on
* the mirror object - will update the object's
* cached region and transformed region
*/
@Override
void updateBoundingLeaf() {
if (boundingLeaf != null && boundingLeaf.switchState.currentSwitchOn) {
region = boundingLeaf.transformedRegion;
} else {
if (regionOfInfluence != null) {
region = regionOfInfluence.copy(region);
region.transform(regionOfInfluence, getCurrentLocalToVworld());
} else {
region = null;
}
}
}
@Override
void setLive(SetLiveState s) {
if (inImmCtx) {
throw new IllegalSharingException(J3dI18N.getString("AlternateAppearanceRetained13"));
}
if (inSharedGroup) {
throw new
IllegalSharingException(J3dI18N.getString("AlternateAppearanceRetained15"));
}
if (inBackgroundGroup) {
throw new
IllegalSceneGraphException(J3dI18N.getString("AlternateAppearanceRetained16"));
}
super.doSetLive(s);
if (appearance != null) {
if (appearance.getInImmCtx()) {
throw new IllegalSharingException(J3dI18N.getString("AlternateAppearanceRetained14"));
}
synchronized(appearance.liveStateLock) {
appearance.setLive(inBackgroundGroup, s.refCount);
}
}
// Create the mirror object
// Initialization of the mirror object during the INSERT_NODE
// message (in updateMirrorObject)
if (mirrorAltApp == null) {
mirrorAltApp = (AlternateAppearanceRetained)this.clone();
// Assign the bounding leaf of this mirror object as null
// it will later be assigned to be the mirror of the alternate app
// bounding leaf object
mirrorAltApp.boundingLeaf = null;
mirrorAltApp.sgAltApp = this;
}
// If bounding leaf is not null, add the mirror object as a user
// so that any changes to the bounding leaf will be received
if (boundingLeaf != null) {
boundingLeaf.mirrorBoundingLeaf.addUser(mirrorAltApp);
}
if ((s.viewScopedNodeList != null) && (s.viewLists != null)) {
s.viewScopedNodeList.add(mirrorAltApp);
s.scopedNodesViewList.add(s.viewLists.get(0));
} else {
s.nodeList.add(mirrorAltApp);
}
if (s.transformTargets != null && s.transformTargets[0] != null) {
s.transformTargets[0].addNode(mirrorAltApp,
Targets.ENV_TARGETS);
s.notifyThreads |= J3dThread.UPDATE_TRANSFORM;
}
// process switch leaf
if (s.switchTargets != null &&
s.switchTargets[0] != null) {
s.switchTargets[0].addNode(mirrorAltApp, Targets.ENV_TARGETS);
}
mirrorAltApp.switchState = s.switchStates.get(0);
s.notifyThreads |= J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER;
// At the end make it live
super.markAsLive();
// Initialize the mirror object, this needs to be done, when
// renderBin is not accessing any of the fields
J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.ALTERNATEAPPEARANCE_CHANGED;
createMessage.args[0] = this;
// a snapshot of all attributes that needs to be initialized
// in the mirror object
createMessage.args[1]= new Integer(INIT_MIRROR);
ArrayList addScopeList = new ArrayList();
for (int i = 0; i < scopes.size(); i++) {
GroupRetained group = scopes.get(i);
tempKey.reset();
group.addAllNodesForScopedAltApp(mirrorAltApp, addScopeList, tempKey);
}
Object[] scopeInfo = new Object[2];
scopeInfo[0] = ((scopes.size() > 0) ? Boolean.TRUE:Boolean.FALSE);
scopeInfo[1] = addScopeList;
createMessage.args[2] = scopeInfo;
if (appearance != null) {
createMessage.args[3] = appearance.mirror;
}
else {
createMessage.args[3] = null;
}
Object[] obj = new Object[2];
obj[0] = boundingLeaf;
obj[1] = (regionOfInfluence != null?regionOfInfluence.clone():null);
createMessage.args[4] = obj;
VirtualUniverse.mc.processMessage(createMessage);
}
/**
* This is called on the parent object
*/
void initMirrorObject(Object[] args) {
Shape3DRetained shape;
Object[] scopeInfo = (Object[]) args[2];
Boolean scoped = (Boolean)scopeInfo[0];
ArrayList shapeList = (ArrayList)scopeInfo[1];
AppearanceRetained app = (AppearanceRetained)args[3];
BoundingLeafRetained bl=(BoundingLeafRetained)((Object[])args[4])[0];
Bounds bnds = (Bounds)((Object[])args[4])[1];
for (int i = 0; i < shapeList.size(); i++) {
shape = ((GeometryAtom)shapeList.get(i)).source;
shape.addAltApp(mirrorAltApp);
}
mirrorAltApp.isScoped = scoped.booleanValue();
if (app != null)
mirrorAltApp.appearance = app;
if (bl != null) {
mirrorAltApp.boundingLeaf = bl.mirrorBoundingLeaf;
mirrorAltApp.region = boundingLeaf.transformedRegion;
} else {
mirrorAltApp.boundingLeaf = null;
mirrorAltApp.region = null;
}
if (bnds != null) {
mirrorAltApp.regionOfInfluence = bnds;
if (mirrorAltApp.region == null) {
mirrorAltApp.region = (Bounds)regionOfInfluence.clone();
mirrorAltApp.region.transform(regionOfInfluence, getLastLocalToVworld());
}
}
else {
mirrorAltApp.regionOfInfluence = null;
}
}
void clearMirrorObject(Object[] args) {
Shape3DRetained shape;
ArrayList shapeList = (ArrayList)args[2];
ArrayList removeScopeList = new ArrayList();
for (int i = 0; i < shapeList.size(); i++) {
shape = ((GeometryAtom)shapeList.get(i)).source;
shape.removeAltApp(mirrorAltApp);
}
mirrorAltApp.isScoped = false;
}
/**
* This clearLive routine first calls the superclass's method, then
* it removes itself to the list of alt app
*/
@Override
void clearLive(SetLiveState s) {
int i, j;
GroupRetained group;
if (appearance != null) {
synchronized(appearance.liveStateLock) {
appearance.clearLive(s.refCount);
}
}
super.clearLive(s);
s.notifyThreads |= J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER;
// Remove this mirror light as users of the bounding leaf
if (mirrorAltApp.boundingLeaf != null)
mirrorAltApp.boundingLeaf.removeUser(mirrorAltApp);
if ((s.viewScopedNodeList != null) && (s.viewLists != null)) {
s.viewScopedNodeList.add(mirrorAltApp);
s.scopedNodesViewList.add(s.viewLists.get(0));
} else {
s.nodeList.add(mirrorAltApp);
}
if (s.transformTargets != null && s.transformTargets[0] != null) {
s.transformTargets[0].addNode(mirrorAltApp,
Targets.ENV_TARGETS);
s.notifyThreads |= J3dThread.UPDATE_TRANSFORM;
}
if (s.switchTargets != null &&
s.switchTargets[0] != null) {
s.switchTargets[0].addNode(mirrorAltApp, Targets.ENV_TARGETS);
}
if (scopes.size() > 0) {
J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.ALTERNATEAPPEARANCE_CHANGED;
createMessage.args[0] = this;
createMessage.args[1]= new Integer(CLEAR_MIRROR);
ArrayList removeScopeList = new ArrayList();
for (i = 0; i < scopes.size(); i++) {
group = scopes.get(i);
tempKey.reset();
group.removeAllNodesForScopedAltApp(mirrorAltApp, removeScopeList, tempKey);
}
createMessage.args[2] = removeScopeList;
VirtualUniverse.mc.processMessage(createMessage);
}
}
@Override
void updateTransformChange() {
}
/**
* Called on mirror object
*/
void updateImmediateTransformChange() {
// If bounding leaf is null, tranform the bounds object
if (boundingLeaf == null) {
if (regionOfInfluence != null) {
region = regionOfInfluence.copy(region);
region.transform(regionOfInfluence,
sgAltApp.getCurrentLocalToVworld());
}
}
}
final void sendMessage(int attrMask, Object attr) {
J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.universe = universe;
createMessage.type = J3dMessage.ALTERNATEAPPEARANCE_CHANGED;
createMessage.args[0] = this;
createMessage.args[1]= new Integer(attrMask);
createMessage.args[2] = attr;
VirtualUniverse.mc.processMessage(createMessage);
}
@Override
void getMirrorObjects(ArrayList leafList, HashKey key) {
leafList.add(mirrorAltApp);
}
/**
* Copies all AlternateAppearance information from
* originalNode
into
* the current node. This method is called from the
* cloneNode
method which is, in turn, called by the
* cloneTree
method.
*
* @param originalNode the original node to duplicate.
* @param forceDuplicate when set to true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @exception RestrictedAccessException if this object is part of a live
* or compiled scenegraph.
*
* @see Node#duplicateNode
* @see Node#cloneTree
* @see NodeComponent#setDuplicateOnCloneTree
*/
void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
throw new RuntimeException("method not implemented");
// super.duplicateAttributes(originalNode, forceDuplicate);
// AlternateAppearance alternate appearance = (AlternateAppearance) originalNode;
// // XXXX: clone appearance
// setInfluencingBounds(alternate appearance.getInfluencingBounds());
// Enumeration elm = alternate appearance.getAllScopes();
// while (elm.hasMoreElements()) {
// // this reference will set correctly in updateNodeReferences() callback
// addScope((Group) elm.nextElement());
// }
// // this reference will set correctly in updateNodeReferences() callback
// setInfluencingBoundingLeaf(alternate appearance.getInfluencingBoundingLeaf());
}
// /**
// * Callback used to allow a node to check if any nodes referenced
// * by that node have been duplicated via a call to cloneTree
.
// * This method is called by cloneTree
after all nodes in
// * the sub-graph have been duplicated. The cloned Leaf node's method
// * will be called and the Leaf node can then look up any node references
// * by using the getNewObjectReference
method found in the
// * NodeReferenceTable
object. If a match is found, a
// * reference to the corresponding Node in the newly cloned sub-graph
// * is returned. If no corresponding reference is found, either a
// * DanglingReferenceException is thrown or a reference to the original
// * node is returned depending on the value of the
// * allowDanglingReferences
parameter passed in the
// * cloneTree
call.
// *
// * NOTE: Applications should not call this method directly.
// * It should only be called by the cloneTree method.
// *
// * @param referenceTable a NodeReferenceTableObject that contains the
// * getNewObjectReference
method needed to search for
// * new object instances.
// * @see NodeReferenceTable
// * @see Node#cloneTree
// * @see DanglingReferenceException
// */
// public void updateNodeReferences(NodeReferenceTable referenceTable) {
// throw new RuntimeException("method not implemented");
//
// Object o;
//
// BoundingLeaf bl = getInfluencingBoundingLeaf();
// if (bl != null) {
// o = referenceTable.getNewObjectReference(bl);
// setInfluencingBoundingLeaf((BoundingLeaf) o);
// }
//
// for (int i=0; i < numScopes(); i++) {
// o = referenceTable.getNewObjectReference(getScope(i));
// setScope((Group) o, i);
// }
// }
}