📄 switchretained.java
字号:
/* * $RCSfile: SwitchRetained.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.8 $ * $Date: 2007/04/20 00:54:41 $ * $State: Exp $ */package javax.media.j3d;import java.util.BitSet;import java.util.ArrayList;/** * The switch node controls which one of its children will be rendered. */class SwitchRetained extends GroupRetained implements TargetsInterface{ static final int GEO_NODES = 0x0001; static final int ENV_NODES = 0x0002; static final int BEHAVIOR_NODES = 0x0004; static final int SOUND_NODES = 0x0008; static final int BOUNDINGLEAF_NODES = 0x0010; /** * The value specifing which child to render. */ int whichChild = Switch.CHILD_NONE; /** * The BitSet specifying which children are to be selected for * rendering. This is used ONLY if whichChild is set to CHILD_MASK. */ BitSet childMask = new BitSet(); /** * The childmask bitset used for rendering */ BitSet renderChildMask = new BitSet(); // A boolean indication that something changed boolean isDirty = true; // switchLevel per key, used in traversing switch children ArrayList switchLevels = new ArrayList(1); // key which identifies a unique path from a locale to this switch link HashKey switchKey = new HashKey(); // switch index counter to identify specific children int switchIndexCount = 0; // for message processing UpdateTargets updateTargets = null; ArrayList childrenSwitchStates = null; SwitchRetained() { this.nodeType = NodeRetained.SWITCH; } /** * Sets which child should be drawn. * @param whichChild the child to choose during a render operation */ // synchronized with clearLive synchronized void setWhichChild(int whichChild, boolean updateAlways) { int i, nchildren; this.whichChild = whichChild; isDirty = true; if (source != null && source.isLive()) { updateTargets = new UpdateTargets(); ArrayList updateList = new ArrayList(1); nchildren = children.size(); switch (whichChild) { case Switch.CHILD_ALL: for (i=0; i<nchildren; i++) { if (renderChildMask.get(i) == false || updateAlways) { renderChildMask.set(i); updateSwitchChild(i, true, updateList); } } break; case Switch.CHILD_NONE: for (i=0; i<nchildren; i++) { if (renderChildMask.get(i) == true || updateAlways) { renderChildMask.clear(i); updateSwitchChild(i, false, updateList); } } break; case Switch.CHILD_MASK: for (i=0; i<nchildren; i++) { if (childMask.get(i) == true) { if (renderChildMask.get(i) == false || updateAlways) { renderChildMask.set(i); updateSwitchChild(i, true, updateList); } } else { if (renderChildMask.get(i) == true || updateAlways) { renderChildMask.clear(i); updateSwitchChild(i, false, updateList); } } } break; default: for (i=0; i<nchildren; i++) { if (i == whichChild) { if (renderChildMask.get(i) == false || updateAlways) { renderChildMask.set(i); updateSwitchChild(i, true, updateList); } } else { if (renderChildMask.get(i) == true || updateAlways) { renderChildMask.clear(i); updateSwitchChild(i, false, updateList); } } } break; } sendMessage(updateList); } dirtyBoundsCache(); } /** * Returns the index of the current child. * @return the default child's index */ int getWhichChild() { return this.whichChild; } /** * Sets current childMask. * @param childMask a BitSet to select the children for rendering */ // synchronized with clearLive synchronized final void setChildMask(BitSet childMask) { int i, nbits, nchildren; if (childMask.size() > this.childMask.size()) { nbits = childMask.size(); } else { nbits = this.childMask.size(); } for (i=0; i<nbits; i++) { if (childMask.get(i)) { this.childMask.set(i); } else { this.childMask.clear(i); } } this.isDirty = true; if (source != null && source.isLive() && whichChild == Switch.CHILD_MASK) { updateTargets = new UpdateTargets(); ArrayList updateList = new ArrayList(1); nchildren = children.size(); for (i=0; i<nchildren; i++) { if (childMask.get(i) == true) { if (renderChildMask.get(i) == false) { renderChildMask.set(i); updateSwitchChild(i, true, updateList); } } else { if (renderChildMask.get(i) == true) { renderChildMask.clear(i); updateSwitchChild(i, false, updateList); } } } sendMessage(updateList); } dirtyBoundsCache(); } void sendMessage(ArrayList updateList) { J3dMessage m ; int i,j,size,threads; Object[] nodesArr, nodes; threads = updateTargets.computeSwitchThreads(); if (threads > 0) { m = new J3dMessage(); m.type = J3dMessage.SWITCH_CHANGED; m.universe = universe; m.threads = threads; m.args[0] = updateTargets; m.args[2] = updateList; UnorderList blnList = updateTargets.targetList[Targets.BLN_TARGETS]; if (blnList != null) { BoundingLeafRetained mbleaf; size = blnList.size(); Object[] boundingLeafUsersArr = new Object[size]; nodesArr = blnList.toArray(false); for (j=0; j<size; j++) { nodes = (Object[])nodesArr[j]; Object[] boundingLeafUsers = new Object[nodes.length]; boundingLeafUsersArr[j] = boundingLeafUsers; for (i=0; i<nodes.length; i++) { mbleaf = (BoundingLeafRetained) nodes[i]; boundingLeafUsers[i] = mbleaf.users.toArray(); } } m.args[1] = boundingLeafUsersArr; } VirtualUniverse.mc.processMessage(m); } UnorderList vpList = updateTargets.targetList[Targets.VPF_TARGETS]; if (vpList != null) { ViewPlatformRetained vp; size = vpList.size(); nodesArr = vpList.toArray(false); for (j=0; j<size; j++) { nodes = (Object[])nodesArr[j]; for (i=0; i<nodes.length; i++) { vp = (ViewPlatformRetained)nodes[i]; vp.processSwitchChanged(); } } } } /** * Returns the current childMask. * @return the current childMask */ final BitSet getChildMask() { return (BitSet)this.childMask.clone(); } /** * Returns the current child. * @return the current child */ Node currentChild() { if ((whichChild < 0) || (whichChild >= children.size())) return null; else return getChild(whichChild); } void updateSwitchChild(int child, boolean switchOn, ArrayList updateList) { int i; int switchLevel; if (inSharedGroup) { for (i=0; i<localToVworldKeys.length; i++) { switchLevel = ((Integer)switchLevels.get(i)).intValue(); traverseSwitchChild(child, localToVworldKeys[i], i, this, false, false, switchOn, switchLevel, updateList); } } else { switchLevel = ((Integer)switchLevels.get(0)).intValue(); traverseSwitchChild(child, null, 0, this, false, false, switchOn, switchLevel, updateList); } } // Switch specific data at SetLive. void setAuxData(SetLiveState s, int index, int hkIndex) { int size; ArrayList switchStates; // Group's setAuxData() super.setAuxData(s, index, hkIndex); switchLevels.add(new Integer(s.switchLevels[index])); int nchildren = children.size(); for (int i=0; i<nchildren; i++) { switchStates = (ArrayList)childrenSwitchStates.get(i); switchStates.add(hkIndex, new SwitchState(true)); } } void setNodeData(SetLiveState s) { super.setNodeData(s); // add this node to parent's childSwitchLink if (s.childSwitchLinks != null) { if(!inSharedGroup || // only add if not already added in sharedGroup !s.childSwitchLinks.contains(this)) { s.childSwitchLinks.add(this); } } // Note that s.childSwitchLinks is updated in super.setLive s.parentSwitchLink = this; if (!inSharedGroup) { setAuxData(s, 0, 0); } else { // For inSharedGroup case. int j, hkIndex; s.hashkeyIndex = new int[s.keys.length]; for(j=0; j<s.keys.length; j++) { hkIndex = s.keys[j].equals(localToVworldKeys, 0, localToVworldKeys.length); if(hkIndex >= 0) { setAuxData(s, j, hkIndex); } else { MasterControl.getCoreLogger().severe("Can't Find matching hashKey in setNodeData."); } s.hashkeyIndex[j] = hkIndex; } } } void setLive(SetLiveState s) { int i,j,k; boolean switchOn; SwitchRetained switchRoot; int size; // save setLiveState Targets[] savedSwitchTargets = s.switchTargets; ArrayList savedSwitchStates = s.switchStates; SwitchRetained[] savedClosestSwitchParents = s.closestSwitchParents; int[] savedClosestSwitchIndices = s.closestSwitchIndices; ArrayList savedChildSwitchLinks = s.childSwitchLinks; GroupRetained savedParentSwitchLink = s.parentSwitchLink; int[] savedHashkeyIndex = s.hashkeyIndex; // update setLiveState for this node s.closestSwitchParents = (SwitchRetained[]) savedClosestSwitchParents.clone(); s.closestSwitchIndices = (int[])savedClosestSwitchIndices.clone(); // Note that s.containsNodesList is updated in super.setLive // Note that s.closestSwitchIndices is updated in super.setLive for (i=0; i< s.switchLevels.length; i++) { s.switchLevels[i]++; s.closestSwitchParents[i] = this; } super.doSetLive(s); initRenderChildMask(); // update switch leaves' compositeSwitchMask // and update switch leaves' switchOn flag if this is top level switch if (inSharedGroup) { for (i=0; i<s.keys.length; i++) { j = s.hashkeyIndex[i]; // j is index in ContainNodes if (j < localToVworldKeys.length) { switchRoot = (s.switchLevels[i] == 0)? this : null; size = children.size(); for (k=0; k<size; k++) { switchOn = renderChildMask.get(k); traverseSwitchChild(k, s.keys[i], j, switchRoot, true, false, switchOn, s.switchLevels[i], null); } } } } else { switchRoot = (s.switchLevels[0] == 0)? this : null; size = children.size(); for (i=0; i<size; i++) { switchOn = renderChildMask.get(i); traverseSwitchChild(i, null, 0, switchRoot, true, false, switchOn, s.switchLevels[0], null); } } // restore setLiveState s.switchTargets = savedSwitchTargets; s.switchStates = savedSwitchStates; s.closestSwitchParents = savedClosestSwitchParents; s.closestSwitchIndices = savedClosestSwitchIndices; for (i=0; i< s.switchLevels.length; i++) { s.switchLevels[i]--; } s.childSwitchLinks = savedChildSwitchLinks; s.parentSwitchLink = savedParentSwitchLink; s.hashkeyIndex = savedHashkeyIndex; super.markAsLive(); } void removeNodeData(SetLiveState s) { int numChildren = children.size(); int i, j; ArrayList switchStates; if (refCount <= 0) { // remove this node from parentSwitchLink's childSwitchLinks // clear childSwitchLinks ArrayList switchLinks; if (parentSwitchLink != null) { for(i=0; i<parentSwitchLink.childrenSwitchLinks.size();i++) { switchLinks = (ArrayList) parentSwitchLink.childrenSwitchLinks.get(i); if (switchLinks.contains(this)) { switchLinks.remove(this); break; } } } for (j=0; j<numChildren; j++) { switchStates = (ArrayList)childrenSwitchStates.get(j); switchStates.clear(); } switchLevels.remove(0); } else { // remove children dependent data int hkIndex; // Must be in reverse, to preserve right indexing. for (i = s.keys.length-1; i >= 0; i--) { hkIndex = s.keys[i].equals(localToVworldKeys, 0, localToVworldKeys.length); if(hkIndex >= 0) { for (j=0; j<numChildren; j++) { switchStates = (ArrayList)childrenSwitchStates.get(j); switchStates.remove(hkIndex); } switchLevels.remove(hkIndex); } } } super.removeNodeData(s); } // synchronized with setWhichChild and setChildMask synchronized void clearLive(SetLiveState s) { Targets[] savedSwitchTargets = s.switchTargets; s.switchTargets = null; super.clearLive(s); s.switchTargets = savedSwitchTargets; } void initRenderChildMask() { int i, nchildren; nchildren = children.size();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -