📄 geometrystructure.java
字号:
BehaviorRetained behav = (BehaviorRetained) node; // cleanup collideEntryList & collideExitList // since we didn't remove // it on remove in removeWakeupOnCollision() // Note that GeometryStructure may run in // parallel with BehaviorStructure when // BS invoke activateBehaviors() to buildTree() // which in turn call addWakeupOnCollision() // to modify collideEntryList at the same time. WakeupOnCollisionEntry wentry; WakeupOnCollisionEntry wentryArr[] = (WakeupOnCollisionEntry []) collideEntryList.toArray(); for (int j=collideEntryList.arraySize()-1; j>=0; j--) { wentry = wentryArr[j]; if (wentry.behav == behav) { collideEntryList.remove(wentry); } } WakeupOnCollisionExit wexit; WakeupOnCollisionExit wexitArr[] = (WakeupOnCollisionExit []) collideExitList.toArray(); for (int j=collideExitList.arraySize()-1; j>=0; j--) { wexit = wexitArr[j]; if (wexit.behav == behav) { collideExitList.remove(wexit); } } } } } if (bhNodeCount < 1) { return; } if (currTree == null) { index = getBHTreeIndex(((BHLeafNode)bhNodeArr[0]).getLocale()); if (index<0) { // Issue 353: must clear array after we are done with it clearBhNodeArr(); return; } currTree = bhTreeArr[index]; } currTree.delete(bhNodeArr, bhNodeCount); // Issue 353: must clear array after we are done with it clearBhNodeArr(); // It is safe to do it here since only GeometryStructure // thread invoke wakeupOnCollisionEntry/Exit .toArray() wakeupOnCollisionEntry.clearMirror(); wakeupOnCollisionMovement.clearMirror(); wakeupOnCollisionExit.clearMirror(); synchronized (collideListLock) { collideEntryList.clearMirror(); collideExitList.clearMirror(); } } private void processBoundsChanged(Object[] nodes, boolean transformChanged) { int index; Object node; clearBhNodeArr(); for (int i = 0; i < nodes.length; i++) { node = nodes[i]; if (node instanceof GeometryAtom) { synchronized (node) { GeometryAtom geomAtom = (GeometryAtom) node; if (geomAtom.bhLeafNode != null) { addToBhNodeArr(geomAtom.bhLeafNode); } } } else if (node instanceof GroupRetained) { GroupRetained group = (GroupRetained) node; if (group.nodeType != NodeRetained.SWITCH) { synchronized (node) { if (group.bhLeafNode != null) { addToBhNodeArr(group.bhLeafNode); } } } } } if (bhNodeCount < 1) { return; } index = getBHTreeIndex(((BHLeafNode)bhNodeArr[0]).getLocale()); if (index >= 0) { bhTreeArr[index].boundsChanged(bhNodeArr, bhNodeCount); } // Issue 353: must clear array after we are done with it clearBhNodeArr(); } private void processTransformChanged(UpdateTargets targets) { int i, j, index; Object[] nodes, nodesArr; UnorderList arrList; int size; clearBhNodeArr(); arrList = targets.targetList[Targets.GEO_TARGETS]; if (arrList != null) { size = arrList.size(); nodesArr = arrList.toArray(false); for (j = 0; j < size; j++) { nodes = (Object[])nodesArr[j]; for (i = 0; i < nodes.length; i++) { GeometryAtom geomAtom = (GeometryAtom) nodes[i]; synchronized (geomAtom) { if (geomAtom.bhLeafNode != null) { addToBhNodeArr(geomAtom.bhLeafNode); } } } } } arrList = targets.targetList[Targets.GRP_TARGETS]; if (arrList != null) { size = arrList.size(); nodesArr = arrList.toArray(false); for ( j = 0; j < size; j++) { nodes = (Object[])nodesArr[j]; for ( i = 0; i < nodes.length; i++) { GroupRetained group = (GroupRetained) nodes[i]; if (group.nodeType != NodeRetained.SWITCH) { synchronized (group) { if (group.bhLeafNode != null) { addToBhNodeArr(group.bhLeafNode); } } } } } } if (bhNodeCount < 1) { return; } index = getBHTreeIndex(((BHLeafNode)bhNodeArr[0]).getLocale()); if (index >= 0) { bhTreeArr[index].boundsChanged(bhNodeArr, bhNodeCount); } // Issue 353: must clear array after we are done with it clearBhNodeArr(); } // This method is called by RenderBin to get a array of possibly visible // sub-trees. // bhTrees mustn't be null. // Return true if bhTree's root in encompass by frustumBBox. boolean getVisibleBHTrees(RenderBin rBin, BoundingBox frustumBBox, Locale locale, long referenceTime, boolean stateChanged, int visibilityPolicy) { int i, j; boolean unviInFB = true; // System.err.println("GeometryStructure : view's locale is " + locale); lock.readLock(); // Issue 353: create a new array list each time rather than passing it // in. This will not generate too much garbage, since we only call // this once per frame and it is very short-lived. ArrayList bhTrees = new ArrayList(); if (bhTreeCount == 1) { // For debugging only. if (J3dDebug.devPhase) { if (J3dDebug.doDebug(J3dDebug.geometryStructure, J3dDebug.LEVEL_2)) { System.err.println("GeometryStructure : In simple case"); System.err.println("GeometryStructure : view's locale is " + locale); System.err.println("GeometryStructure : bhTreeArr[0].locale is " + bhTreeArr[0].locale); } } // One locale case - Lets make the simple case fast. synchronized(visLock) { unviInFB = bhTreeArr[0].getVisibleBHTrees(rBin, bhTrees, frustumBBox, referenceTime, stateChanged, visibilityPolicy, true); } } else { // Multiple locale case. // For debugging only. if (J3dDebug.devPhase) J3dDebug.doDebug(J3dDebug.geometryStructure, J3dDebug.LEVEL_2, "GeometryStructure : bhTreeCount is " + universe.geometryStructure.bhTreeCount + " view's locale is " + locale + "\n"); BoundingBox localeFrustumBBox = new BoundingBox(); synchronized(visLock) { for (j=0; j<bhTreeCount; j++) { if (J3dDebug.devPhase) { J3dDebug.doDebug(J3dDebug.geometryStructure, J3dDebug.LEVEL_2, "GeometryStructure : bhTreeArr[" + j + "] is " + bhTreeArr[j].locale + "\n"); } if (!locale.hiRes.equals(bhTreeArr[j].locale.hiRes)) { bhTreeArr[j].locale.hiRes.difference(locale.hiRes, localeTrans); if (J3dDebug.devPhase) { J3dDebug.doDebug(J3dDebug.geometryStructure, J3dDebug.LEVEL_2, "localeTrans is " + localeTrans + "GeometryStructure : localeFrustumBBox " + localeFrustumBBox + "\n" ); } // Need to translate view frustumBBox here. localeFrustumBBox.lower.x = frustumBBox.lower.x + localeTrans.x; localeFrustumBBox.lower.y = frustumBBox.lower.y + localeTrans.y; localeFrustumBBox.lower.z = frustumBBox.lower.z + localeTrans.z; localeFrustumBBox.upper.x = frustumBBox.upper.x + localeTrans.x; localeFrustumBBox.upper.y = frustumBBox.upper.y + localeTrans.y; localeFrustumBBox.upper.z = frustumBBox.upper.z + localeTrans.z; } else { frustumBBox.copy(localeFrustumBBox); } if(!(bhTreeArr[j].getVisibleBHTrees(rBin, bhTrees, localeFrustumBBox, referenceTime, stateChanged, visibilityPolicy, false))) { unviInFB = false; } } } } lock.readUnlock(); return unviInFB; } GeometryAtom[] pickAll(Locale locale, PickShape shape) { int i; UnorderList hitList = new UnorderList(BHNode.class); hitList.clear(); lock.readLock(); i = getBHTreeIndex(locale); if (i < 0) { lock.readUnlock(); return null; } bhTreeArr[i].select(shape, hitList); lock.readUnlock(); int size = hitList.size(); if (size < 1) return null; BHNode[] hitArr = (BHNode []) hitList.toArray(false); GeometryAtom[] geometryAtoms = new GeometryAtom[size]; for (i=0; i<size; i++) { geometryAtoms[i] = (GeometryAtom)(((BHLeafNode)hitArr[i]).leafIF); } return geometryAtoms; } GeometryAtom pickAny(Locale locale, PickShape shape) { int i; BHNode hitNode = null; lock.readLock(); i = getBHTreeIndex(locale); if (i < 0) { lock.readUnlock(); return null; } hitNode = bhTreeArr[i].selectAny(shape); lock.readUnlock(); if (hitNode == null) return null; return (GeometryAtom)(((BHLeafNode)hitNode).leafIF); } void addWakeupOnCollision(WakeupOnCollisionEntry w) { boolean needTrigger = true; // Cleanup, since collideEntryList did not remove // its condition in removeWakeupOnCollision synchronized (collideListLock) { WakeupOnCollisionEntry collideEntryArr[] = (WakeupOnCollisionEntry []) collideEntryList.toArray(); WakeupOnCollisionEntry wentry; for (int i=collideEntryList.arraySize()-1; i>=0; i--) { wentry = collideEntryArr[i]; if ((wentry.behav == w.behav) && (wentry.geometryAtoms == w.geometryAtoms)) { collideEntryList.remove(i); needTrigger = false; break; } } } // add to wakeup list wakeupOnCollisionEntry.add(w); w.updateCollisionBounds(false); // check for collision and triggered event BHLeafInterface target = collide(w.behav.locale, w.accuracyMode, w.geometryAtoms, w.vwcBounds, w.boundingLeaf, w.armingNode, null); if (target != null) { collideEntryList.add(w); w.setTarget(target); } if ((target != null) && (needTrigger)) { w.setTriggered(); } } void addWakeupOnCollision(WakeupOnCollisionExit w) { // Cleanup, since collideExitList did not remove // its condition in removeWakeupOnCollision boolean needTrigger = true; synchronized (collideListLock) { WakeupOnCollisionExit collideExitArr[] = (WakeupOnCollisionExit []) collideExitList.toArray(); WakeupOnCollisionExit wexit; for (int i=collideExitList.arraySize()-1; i>=0; i--) { wexit = collideExitArr[i]; if ((wexit.behav == w.behav) && (wexit.geometryAtoms == w.geometryAtoms)) { collideExitList.remove(i); needTrigger = false; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -