diff options
author | Harvey Harrison <[email protected]> | 2015-04-19 21:02:06 -0700 |
---|---|---|
committer | Harvey Harrison <[email protected]> | 2015-04-19 21:02:06 -0700 |
commit | 7a2e20caac9db6f789a7b3fab344b9758af45335 (patch) | |
tree | b5236ff2570178de356eab569225108948eb4d30 /src/javax/media/j3d/SharedGroupRetained.java | |
parent | f76ce302c4bb2a9f03bbee571ec5d05c29633023 (diff) |
j3dcore: flatten the directory structure a bit
Signed-off-by: Harvey Harrison <[email protected]>
Diffstat (limited to 'src/javax/media/j3d/SharedGroupRetained.java')
-rw-r--r-- | src/javax/media/j3d/SharedGroupRetained.java | 931 |
1 files changed, 931 insertions, 0 deletions
diff --git a/src/javax/media/j3d/SharedGroupRetained.java b/src/javax/media/j3d/SharedGroupRetained.java new file mode 100644 index 0000000..1d5b3d3 --- /dev/null +++ b/src/javax/media/j3d/SharedGroupRetained.java @@ -0,0 +1,931 @@ +/* + * Copyright 1996-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; + +/** + * The SharedGroup node provides the ability to share a scene graph from + * multiple other scene graphs through the use of a Link node. + */ + +class SharedGroupRetained extends GroupRetained implements TargetsInterface { + + /* + static final int ILLEGAL_LEAF_MASK = + 1 << NodeRetained.BACKGROUND | + 1 << NodeRetained.BEHAVIOR | + 1 << NodeRetained.CLIP | + 1 << NodeRetained.LINEARFOG | + 1 << NodeRetained.EXPONENTIALFOG | + 1 << NodeRetained.SOUNDSCAPE | + 1 << NodeRetained.VIEWPLATFORM | + 1 << NodeRetained.BOUNDINGLEAF; + */ + +// The current list of child transform group nodes or link nodes +// under a transform group +ArrayList<NodeRetained> childTransformLinks = new ArrayList<NodeRetained>(1); + + // key which identifies a unique path from a + // locale to this transform group + HashKey currentKey = new HashKey(); + + // key which identifies a unique path from a locale to this switch link + HashKey switchKey = new HashKey(); + +/** + * The Shared Group Node's parent vector. + */ +Vector<NodeRetained> parents = new Vector<NodeRetained>(1); + + // J3d copy. + CachedTargets[] j3dCTs = null; + + // User copy. + CachedTargets[] cachedTargets = null; + + // A bitmask of the types in targets for transform targets + int localTargetThreads = 0; + // combined localTargetThreads and decendants' localTargetThreads + int targetThreads = 0; + + ArrayList<SwitchState> switchStates = null; + + SharedGroupRetained() { + this.nodeType = NodeRetained.SHAREDGROUP; + } + + // SharedGroup specific data at SetLive. + @Override + void setAuxData(SetLiveState s, int index, int hkIndex) { + int i, size; + + // Group's setAuxData() + super.setAuxData(s, index, hkIndex); + + branchGroupPaths.add(hkIndex, s.branchGroupPaths.get(index)); + + if (orderedPaths == null) { + orderedPaths = new ArrayList<OrderedPath>(1); + } + orderedPaths.add(hkIndex, s.orderedPaths.get(index)); + + if (switchStates == null) { + switchStates = new ArrayList<SwitchState>(1); + } + switchStates.add(hkIndex, s.switchStates.get(index)); + + if (viewLists == null) { + viewLists = new ArrayList<ArrayList<View>>(1); + } + // If there are some ViewSpecificGroups in the path above this SharedGroup + // System.err.println("====> hkIndex = "+hkIndex+" s.viewLists = "+s.viewLists); + if (s.viewLists != null) { + viewLists.add(hkIndex, s.viewLists.get(index)); + } + else { + viewLists.add(hkIndex, null); + } + + if (lights == null) { + lights = new ArrayList<ArrayList<LightRetained>>(1); + } + if (s.lights != null) { + lights.add(hkIndex, s.lights.get(index)); + } + else { + lights.add(hkIndex, null); + } + + if (fogs == null) { + fogs = new ArrayList<ArrayList<FogRetained>>(1); + } + if (s.fogs != null) { + fogs.add(hkIndex, s.fogs.get(index)); + } + else { + fogs.add(hkIndex, null); + } + + + if (modelClips == null) { + modelClips = new ArrayList<ArrayList<ModelClipRetained>>(1); + } + if (s.modelClips != null) { + modelClips.add(hkIndex, s.modelClips.get(index)); + } + else { + modelClips.add(hkIndex, null); + } + + + if (altAppearances == null) { + altAppearances = new ArrayList<ArrayList<AlternateAppearanceRetained>>(1); + } + if (s.altAppearances != null) { + altAppearances.add(hkIndex, s.altAppearances.get(index)); + } + else { + altAppearances.add(hkIndex, null); + } + } + + + @Override + void setNodeData(SetLiveState s) { + + // For inSharedGroup case. + int i, j, len; + + if (localToVworld == null) { + localToVworld = new Transform3D[s.keys.length][]; + localToVworldIndex = new int[s.keys.length][]; + localToVworldKeys = new HashKey[s.keys.length]; + cachedTargets = new CachedTargets[s.keys.length]; + len=0; + } + else { + + int newLen = localToVworld.length + s.keys.length; + + Transform3D newTList[][] = new Transform3D[newLen][]; + HashKey newHList[] = new HashKey[newLen]; + int newIndexList[][] = new int[newLen][]; + CachedTargets newTargets[] = new CachedTargets[newLen]; + + len = localToVworld.length; + + // Copy the existing data into the newly created data objects. + System.arraycopy(localToVworld, 0, newTList, 0, localToVworld.length); + System.arraycopy(localToVworldIndex, 0, newIndexList, 0, + localToVworldIndex.length); + System.arraycopy(localToVworldKeys, 0, newHList, 0, + localToVworldKeys.length); + System.arraycopy(cachedTargets, 0, newTargets, 0, + cachedTargets.length); + + localToVworld = newTList; + localToVworldIndex = newIndexList; + localToVworldKeys = newHList; + cachedTargets = newTargets; + } + + int[] hkIndex = new int[1]; + int hkIndexPlus1, blkSize; + + s.hashkeyIndex = new int[s.keys.length]; + + // This should appear before super.setNodeData() if it exists + s.parentBranchGroupPaths = branchGroupPaths; + + for(i=len, j=0; i<localToVworld.length; i++, j++) { + + if(s.keys[j].equals(localToVworldKeys, hkIndex, 0, i)) { + MasterControl.getCoreLogger().severe("Found matching hashKey in setNodeData."); + } + s.hashkeyIndex[j] = hkIndex[0]; + + + if(hkIndex[0] == i) { // Append to last. + localToVworldKeys[i] = s.keys[j]; + localToVworld[i] = s.currentTransforms[j]; + localToVworldIndex[i] = s.currentTransformsIndex[j]; + } + else { // Insert in between array elements. + hkIndexPlus1 = hkIndex[0] + 1; + blkSize = i - hkIndex[0]; + + // Shift the later portion of array elements by one position. + // This is the make room for the new data entry. + System.arraycopy(localToVworldKeys, hkIndex[0], localToVworldKeys, + hkIndexPlus1, blkSize); + System.arraycopy(localToVworld, hkIndex[0], localToVworld, + hkIndexPlus1, blkSize); + System.arraycopy(localToVworldIndex, hkIndex[0], localToVworldIndex, + hkIndexPlus1, blkSize); + System.arraycopy(cachedTargets, hkIndex[0], cachedTargets, + hkIndexPlus1, blkSize); + + localToVworldKeys[hkIndex[0]] = s.keys[j]; + localToVworld[hkIndex[0]] = s.currentTransforms[j]; + localToVworldIndex[hkIndex[0]] = s.currentTransformsIndex[j]; + } + + // System.err.println("SG: j = "+j+" hkIndex[0] = "+hkIndex[0]+" s.keys[j] = "+s.keys[j]); + // For now (1.2.1beta2) only. We cleanup setLive, and clearLive in + // next release. + setAuxData(s, j, hkIndex[0]); + } + + // The SetLiveState need the reflect the new state of this SharedGroup. + // The SetLiveState will get reset back in SetLive, after all children of this + // node have been set live. + s.localToVworld = localToVworld; + s.localToVworldIndex = localToVworldIndex; + s.localToVworldKeys = localToVworldKeys; + s.orderedPaths = orderedPaths; + s.switchStates = switchStates; + + // Note that s.childSwitchLinks is updated in super.setLive + s.childTransformLinks = childTransformLinks; + s.parentTransformLink = this; + s.parentSwitchLink = this; + s.viewLists = viewLists; + s.lights = lights; + s.fogs = fogs; + s.altAppearances = altAppearances; + s.modelClips = modelClips; + } + + @Override + void setLive(SetLiveState s) { + + int i,j; + Targets[] newTargets = null; + + // save setLiveState + Transform3D savedLocalToVworld[][] = s.localToVworld; + int savedLocalToVworldIndex[][] = s.localToVworldIndex; + HashKey savedLocalToVworldKeys[] = s.localToVworldKeys; + ArrayList<OrderedPath> savedOrderedPaths = s.orderedPaths; + ArrayList<ArrayList<View>> savedViewList = s.viewLists; + ArrayList<ArrayList<LightRetained>> savedLights = s.lights; + ArrayList<ArrayList<FogRetained>> savedFogs = s.fogs; + ArrayList<ArrayList<ModelClipRetained>> savedMclips = s.modelClips; + ArrayList<ArrayList<AlternateAppearanceRetained>> savedAltApps = s.altAppearances; + + SharedGroupRetained savedLastSharedGroup = s.lastSharedGroup; + Targets[] savedSwitchTargets = s.switchTargets; + ArrayList<SwitchState> savedSwitchStates = s.switchStates; + ArrayList<NodeRetained> savedChildSwitchLinks = s.childSwitchLinks; + GroupRetained savedParentSwitchLink = s.parentSwitchLink; + ArrayList<NodeRetained> savedChildTransformLinks = s.childTransformLinks; + GroupRetained savedParentTransformLink = s.parentTransformLink; + int[] savedHashkeyIndex = s.hashkeyIndex; + + // update setLiveState for this node + // Note that s.containsNodesList is updated in super.setLive + s.lastSharedGroup = this; + + Targets[] savedTransformTargets = s.transformTargets; + + int numPaths = s.keys.length; + newTargets = new Targets[numPaths]; + for(i=0; i<numPaths; i++) { + if (s.transformLevels[i] >= 0) { + newTargets[i] = new Targets(); + } else { + newTargets[i] = null; + } + } + s.transformTargets = newTargets; + + super.setLive(s); + + int hkIndex; + for(i=0; i<numPaths; i++) { + if (s.transformTargets[i] != null) { + hkIndex = s.hashkeyIndex[i]; + cachedTargets[hkIndex] = s.transformTargets[i].snapShotInit(); + } + } + // Assign data in cachedTargets to j3dCTs. + j3dCTs = new CachedTargets[cachedTargets.length]; + copyCachedTargets(TargetsInterface.TRANSFORM_TARGETS, j3dCTs); + + computeTargetThreads(TargetsInterface.TRANSFORM_TARGETS, cachedTargets); + + + // restore setLiveState + s.localToVworld = savedLocalToVworld; + s.localToVworldIndex = savedLocalToVworldIndex; + s.localToVworldKeys = savedLocalToVworldKeys; + s.orderedPaths = savedOrderedPaths; + s.viewLists = savedViewList; + + s.lights = savedLights; + s.fogs = savedFogs; + s.modelClips = savedMclips; + s.altAppearances = savedAltApps; + + s.lastSharedGroup = savedLastSharedGroup; + s.switchTargets = savedSwitchTargets; + s.switchStates = savedSwitchStates; + + s.childSwitchLinks = savedChildSwitchLinks; + s.parentSwitchLink = savedParentSwitchLink; + s.childTransformLinks = savedChildTransformLinks; + s.parentTransformLink = savedParentTransformLink; + + s.transformTargets = savedTransformTargets; + s.hashkeyIndex = savedHashkeyIndex; +/* +// XXXX : port this + for (int i=0; i < children.size(); i++) { + if ((childContains[i][0] & ILLEGAL_LEAF_MASK) != 0) { + throw new IllegalSharingException(J3dI18N.getString("SharedGroupRetained0")); } + } +*/ + } + + + /** + * remove the localToVworld transform for a node. + */ + @Override + void removeNodeData(SetLiveState s) { + + ArrayList switchTargets; + int i,j; + + if (refCount <= 0) { + localToVworld = null; + localToVworldIndex = null; + localToVworldKeys = null; + // restore to default and avoid calling clear() + // that may clear parent reference branchGroupPaths + // Note that this function did not invoke super.removeNodeData() + branchGroupPaths = new ArrayList<BranchGroupRetained[]>(1); + orderedPaths = null; + switchStates = null; + cachedTargets = null; + targetThreads = 0; + lights.clear(); + fogs.clear(); + modelClips.clear(); + altAppearances.clear(); + } + else { + int index, len; + + // Remove the localToVworld key + int newLen = localToVworld.length - s.keys.length; + + Transform3D[][] newTList = new Transform3D[newLen][]; + HashKey[] newHList = new HashKey[newLen]; + Transform3D newChildTList[][] = null; + int[][] newIndexList = new int[newLen][]; + CachedTargets[] newTargets = new CachedTargets[newLen]; + + int[] tempIndex = new int[s.keys.length]; + int curStart =0, newStart =0; + boolean found = false; + + for(i=0;i<s.keys.length;i++) { + index = s.keys[i].equals(localToVworldKeys, 0, localToVworldKeys.length); + + tempIndex[i] = index; + + if(index >= 0) { + found = true; + if(index == curStart) { + curStart++; + } + else { + len = index - curStart; + System.arraycopy(localToVworld, curStart, newTList, newStart, len); + System.arraycopy(localToVworldIndex, curStart, newIndexList, + newStart, len); + System.arraycopy(localToVworldKeys, curStart, newHList, newStart, len); + System.arraycopy(cachedTargets, curStart, newTargets, + newStart, len); + + curStart = index+1; + newStart = newStart + len; + } + } + else { + found = false; + MasterControl.getCoreLogger().severe("Can't Find matching hashKey in SG.removeNodeData."); + } + } + + if((found == true) && (curStart < localToVworld.length)) { + len = localToVworld.length - curStart; + System.arraycopy(localToVworld, curStart, newTList, newStart, len); + System.arraycopy(localToVworldIndex, curStart, newIndexList, + newStart, len); + System.arraycopy(localToVworldKeys, curStart, newHList, newStart, len); + System.arraycopy(cachedTargets, curStart, newTargets, + newStart, len); + } + + // Must be in reverse, to preserve right indexing. + for (i = tempIndex.length-1; i >= 0 ; i--) { + if(tempIndex[i] >= 0) { + branchGroupPaths.remove(tempIndex[i]); + orderedPaths.remove(tempIndex[i]); + switchStates.remove(tempIndex[i]); + lights.remove(tempIndex[i]); + fogs.remove(tempIndex[i]); + modelClips.remove(tempIndex[i]); + altAppearances.remove(tempIndex[i]); + } + } + + localToVworld = newTList; + localToVworldIndex = newIndexList; + localToVworldKeys = newHList; + cachedTargets = newTargets; + } + s.localToVworld = localToVworld; + s.localToVworldIndex = localToVworldIndex; + s.localToVworldKeys = localToVworldKeys; + s.orderedPaths = orderedPaths; + s.switchStates = switchStates; + s.viewLists = viewLists; + s.lights = lights; + s.fogs = fogs; + s.modelClips = modelClips; + s.altAppearances = altAppearances; + } + + @Override + void clearLive(SetLiveState s) { + + int i,j,k, index; + + Transform3D savedLocalToVworld[][] = s.localToVworld; + int savedLocalToVworldIndex[][] = s.localToVworldIndex; + HashKey savedLocalToVworldKeys[] = s.localToVworldKeys; + ArrayList<OrderedPath> savedOrderedPaths = s.orderedPaths; + ArrayList<ArrayList<View>> savedViewLists = s.viewLists; + + ArrayList<ArrayList<LightRetained>> savedLights = s.lights; + ArrayList<ArrayList<FogRetained>> savedFogs = s.fogs; + ArrayList<ArrayList<ModelClipRetained>> savedMclips = s.modelClips; + ArrayList<ArrayList<AlternateAppearanceRetained>> savedAltApps = s.altAppearances; + + Targets[] savedSwitchTargets = s.switchTargets; + Targets[] savedTransformTargets = s.transformTargets; + // no need to gather targets from sg in clear live + s.transformTargets = null; + s.switchTargets = null; + + + // XXXX: This is a hack since removeNodeData is called before + // children are clearLives + int[] tempIndex = null; + // Don't keep the indices if everything will be cleared + if (s.keys.length != localToVworld.length) { + tempIndex = new int[s.keys.length]; + for (i = s.keys.length-1; i >= 0; i--) { + tempIndex[i] = s.keys[i].equals(localToVworldKeys, 0, localToVworldKeys.length); + } + } + + super.clearLive(s); + // Do this after children clearlive since part of the viewLists may get cleared + // during removeNodeData + if(refCount <= 0) { + viewLists.clear(); + } + else { + // Must be in reverse, to preserve right indexing. + for (i = tempIndex.length-1; i >= 0 ; i--) { + if(tempIndex[i] >= 0) { + viewLists.remove(tempIndex[i]); + } + } + } + + // restore setLiveState from it's local variables. + // removeNodeData has altered these variables. + s.localToVworld = savedLocalToVworld; + s.localToVworldIndex = savedLocalToVworldIndex; + s.localToVworldKeys = savedLocalToVworldKeys; + s.orderedPaths = savedOrderedPaths; + s.viewLists = savedViewLists; + s.lights = savedLights; + s.fogs = savedFogs; + s.modelClips = savedMclips; + s.altAppearances = savedAltApps; + s.transformTargets = savedTransformTargets; + s.switchTargets = savedSwitchTargets; + } + + void updateChildLocalToVworld(HashKey key, int index, + ArrayList<TransformGroupRetained> dirtyTransformGroups, + ArrayList keySet, + UpdateTargets targets, + ArrayList blUsers) { + + LinkRetained ln; + TransformGroupRetained tg; + int i,j; + Object obj; + + CachedTargets ct = j3dCTs[index]; + if (ct != null) { + targets.addCachedTargets(ct); + if (ct.targetArr[Targets.BLN_TARGETS] != null) { + gatherBlUsers(blUsers, ct.targetArr[Targets.BLN_TARGETS]); + } + } + + synchronized(childTransformLinks) { + for (i=0; i<childTransformLinks.size(); i++) { + obj = childTransformLinks.get(i); + + if (obj instanceof TransformGroupRetained) { + tg = (TransformGroupRetained)obj; + tg.updateChildLocalToVworld( + tg.localToVworldKeys[index], index, + dirtyTransformGroups, keySet, + targets, blUsers); + + + } else { // LinkRetained + ln = (LinkRetained)obj; + currentKey.set(key); + currentKey.append(LinkRetained.plus).append(ln.nodeId); + if (ln.sharedGroup.localToVworldKeys != null) { + j = currentKey.equals(ln.sharedGroup.localToVworldKeys,0, + ln.sharedGroup.localToVworldKeys.length); + if(j < 0) { + System.err.println("SharedGroupRetained : Can't find hashKey"); + } + + if (j < ln.sharedGroup.localToVworldKeys.length) { + ln.sharedGroup.updateChildLocalToVworld( + ln.sharedGroup.localToVworldKeys[j], j, + dirtyTransformGroups, keySet, + targets, blUsers); + } + } + } + } + } + } + + void traverseSwitchChild(int child, HashKey key, + int index, SwitchRetained switchRoot, + boolean init, boolean swChanged, + boolean switchOn, int switchLevel, + ArrayList<SwitchState> updateList) { + + SwitchRetained sw; + LinkRetained ln; + Object obj; + int i,j,k; + + ArrayList<NodeRetained> childSwitchLinks = childrenSwitchLinks.get(child); + for (i=0; i<childSwitchLinks.size(); i++) { + obj = childSwitchLinks.get(i); + + if (obj instanceof SwitchRetained) { + sw = (SwitchRetained)obj; + for(j=0; j<sw.children.size(); j++) { + sw.traverseSwitchChild(j, key, index, switchRoot, + init, swChanged, switchOn, switchLevel, updateList); + } + } else { // LinkRetained + ln = (LinkRetained)obj; + switchKey.set(key); + switchKey.append(LinkRetained.plus).append(ln.nodeId); + + if (ln.sharedGroup.localToVworldKeys != null) { + + j = switchKey.equals(ln.sharedGroup.localToVworldKeys,0, + ln.sharedGroup.localToVworldKeys.length); + if(j < 0) { + System.err.println("SharedGroupRetained : Can't find hashKey"); + } + + if (j < ln.sharedGroup.localToVworldKeys.length) { + for(k=0; k<ln.sharedGroup.children.size(); k++) { + ln.sharedGroup.traverseSwitchChild(k, + ln.sharedGroup. + localToVworldKeys[j], + j, switchRoot, init, + swChanged, switchOn, + switchLevel, updateList); + } + } + } + } + } + } + + void traverseSwitchParent() { + int i; + + for(i=0; i<parents.size(); i++) { + NodeRetained ln = parents.get(i); + if (ln.parentSwitchLink != null) { + if (parentSwitchLink instanceof SwitchRetained) { + ((SwitchRetained)parentSwitchLink).traverseSwitchParent(); + } else if (parentSwitchLink instanceof SharedGroupRetained) { + ((SharedGroupRetained)parentSwitchLink).traverseSwitchParent(); + } + } + } + } + + // Top level compile call, same as BranchGroup.compile() + void compile() { + + if (source.isCompiled() || VirtualUniverse.mc.disableCompile) + return; + + if (J3dDebug.devPhase && J3dDebug.debug) { + J3dDebug.doDebug(J3dDebug.compileState, J3dDebug.LEVEL_3, + "SharedGroupRetained.compile()....\n"); + } + + CompileState compState = new CompileState(); + + isRoot = true; + + compile(compState); + merge(compState); + + if (J3dDebug.devPhase && J3dDebug.debug) { + if (J3dDebug.doDebug(J3dDebug.compileState, J3dDebug.LEVEL_3)) { + compState.printStats(); + } + if (J3dDebug.doDebug(J3dDebug.compileState, J3dDebug.LEVEL_5)) { + this.traverse(false, 1); + System.err.println(); + } + } + + } + + /** + * Returns the Link nodes that refer to this SharedGroup node + * @return An array of Link nodes + */ + Link[] getLinks() { + Link[] links; + // make sure this method is MT-safe + synchronized(parents) { + int n = parents.size(); + // allocate new array + links = new Link[n]; + for(int i = 0; i < n; i++) { + // copy Link nodes from this node's list of parents + links[i] = (Link)((LinkRetained)parents.elementAt(i)).source; + } + } + return links; + } + + @Override + void insertChildrenData(int index) { + if (childrenSwitchLinks == null) { + childrenSwitchLinks = new ArrayList<ArrayList<NodeRetained>>(1); + } + childrenSwitchLinks.add(index, new ArrayList<NodeRetained>(1)); + } + + @Override + void appendChildrenData() { + if (childrenSwitchLinks == null) { + childrenSwitchLinks = new ArrayList<ArrayList<NodeRetained>>(1); + } + childrenSwitchLinks.add(new ArrayList<NodeRetained>(1)); + } + + @Override + void removeChildrenData(int index) { + ArrayList<NodeRetained> oldSwitchLinks = childrenSwitchLinks.get(index); + oldSwitchLinks.clear(); + childrenSwitchLinks.remove(index); + } + + + // *************************** + // TargetsInterface methods + // *************************** + + @Override + public int getTargetThreads(int type) { + if (type == TargetsInterface.TRANSFORM_TARGETS) { + return targetThreads; + } else { + System.err.println("getTargetThreads: wrong arguments"); + return -1; + } + } + + @Override + TargetsInterface getClosestTargetsInterface(int type) { + return this; + } + + // re-evalute localTargetThreads using newCachedTargets and + // re-evaluate targetThreads + @Override + public void computeTargetThreads(int type, + CachedTargets[] newCachedTargets) { + + localTargetThreads = 0; + if (type == TargetsInterface.TRANSFORM_TARGETS) { + for(int i=0; i<newCachedTargets.length; i++) { + if (newCachedTargets[i] != null) { + localTargetThreads |= newCachedTargets[i].computeTargetThreads(); + } + } + targetThreads = localTargetThreads; + + int numLinks = childTransformLinks.size(); + TargetsInterface childLink; + NodeRetained node; + + for(int i=0; i<numLinks; i++) { + node = (NodeRetained)childTransformLinks.get(i); + if (node.nodeType == NodeRetained.LINK) { + childLink = (TargetsInterface) + ((LinkRetained)node).sharedGroup; + } else { + childLink = (TargetsInterface) node; + } + if (childLink != null) { + targetThreads |= + childLink.getTargetThreads(TargetsInterface.TRANSFORM_TARGETS); + } + } + + } else { + System.err.println("computeTargetsThreads: wrong arguments"); + } + } + + // re-compute localTargetThread, targetThreads and + // propagate changes to ancestors + @Override + public void updateTargetThreads(int type, CachedTargets[] newCachedTargets) { + // type is ignored here, only need for SharedGroup + if (type == TargetsInterface.TRANSFORM_TARGETS) { + computeTargetThreads(type, newCachedTargets); + if (parentTransformLink != null) { + TargetsInterface pti = (TargetsInterface)parentTransformLink; + pti.propagateTargetThreads(TargetsInterface.TRANSFORM_TARGETS, + targetThreads); + } + } else { + System.err.println("updateTargetThreads: wrong arguments"); + } + } + + // re-evaluate targetThreads using childTargetThreads and + // propagate changes to ancestors + @Override + public void propagateTargetThreads(int type, int childTargetThreads) { + if (type == TargetsInterface.TRANSFORM_TARGETS) { + LinkRetained ln; + // XXXX : For now we'll OR more than exact. + //targetThreads = localTargetThreads | childTargetThreads; + targetThreads = targetThreads | childTargetThreads; + for(int i=0; i<parents.size(); i++) { + ln = (LinkRetained) parents.elementAt(i); + if (ln.parentTransformLink != null) { + TargetsInterface pti = + (TargetsInterface)ln.parentTransformLink; + pti.propagateTargetThreads(type, targetThreads); + } + } + } else { + System.err.println("propagateTargetThreads: wrong arguments"); + } + } + + @Override + public void updateCachedTargets(int type, CachedTargets[] newCt) { + if (type == TargetsInterface.TRANSFORM_TARGETS) { + j3dCTs = newCt; + } else { + System.err.println("updateCachedTargets: wrong arguments"); + } + } + + @Override + public void copyCachedTargets(int type, CachedTargets[] newCt) { + if (type == TargetsInterface.TRANSFORM_TARGETS) { + int size = cachedTargets.length; + for (int i=0; i<size; i++) { + newCt[i] = cachedTargets[i]; + } + } else { + System.err.println("copyCachedTargets: wrong arguments"); + } + } + + @Override + public CachedTargets getCachedTargets(int type, int index, int child) { + if (type == TargetsInterface.SWITCH_TARGETS) { + // child info is not used, SG does not have per child states + if (index < switchStates.size()) { + SwitchState switchState = switchStates.get(index); + return switchState.cachedTargets; + } else { + return null; + } + } else { + // type == TargetsInterface.TRANSFORM_TARGETS + return cachedTargets[index]; + } + } + + @Override + public void resetCachedTargets(int type, + CachedTargets[] newCtArr,int child) { + if (type == TargetsInterface.SWITCH_TARGETS) { + // child info is not used, SG does not have per child states + SwitchState switchState; + if (newCtArr.length != switchStates.size()) { + System.err.println("resetCachedTargets: unmatched length!" + + newCtArr.length + " " + switchStates.size()); + System.err.println(" resetCachedTargets: " + this); + } + for (int i=0; i<newCtArr.length; i++) { + switchState = switchStates.get(i); + switchState.cachedTargets = newCtArr[i]; + } + + } else { + // type == TargetsInterface.TRANSFORM_TARGETS + cachedTargets = newCtArr; + } + } + +@Override +public ArrayList<SwitchState> getTargetsData(int type, int index) { + // index is ignores for SharedGroup + if (type == TargetsInterface.SWITCH_TARGETS) { + return switchStates; + } + else { + System.err.println("getTargetsData: wrong arguments"); + return null; + } +} + + @Override + void childDoSetLive(NodeRetained child, int childIndex, SetLiveState s) { + + int i; + s.childSwitchLinks = childrenSwitchLinks.get(childIndex); + s.switchStates = switchStates; + + if(child!=null) + child.setLive(s); + } + + void childCheckSetLive(NodeRetained child, int childIndex, SetLiveState s) { + s.childTransformLinks = childTransformLinks; + s.parentTransformLink = this; + child.setLive(s); + } + + /** + * Make the boundsCache of this node and all its parents dirty + */ + @Override + void dirtyBoundsCache() { + // Possible optimisation is to not traverse up the tree + // if the cachedBounds==null. However this is not the case + // if the node is the child of a SharedGroup + if (VirtualUniverse.mc.cacheAutoComputedBounds) { + // Issue 514 : NPE in Wonderland : triggered in cached bounds computation + validCachedBounds = false; + synchronized(parents) { + Enumeration e = parents.elements(); + while(e.hasMoreElements()) { + LinkRetained parent = (LinkRetained) e.nextElement(); + if (parent!=null) { + parent.dirtyBoundsCache(); + } + } + } + } + } +} |