📄 geometrystructure.java
字号:
} } // add condition wakeupOnCollisionExit.add(w); w.updateCollisionBounds(false); BHLeafInterface target = collide(w.behav.locale, w.accuracyMode, w.geometryAtoms, w.vwcBounds, w.boundingLeaf, w.armingNode, null); if (target != null) { // store the target that cause this condition to collide // this is used when this condition is triggered. w.setTarget(target); collideExitList.add(w); } if (!needTrigger) { return; } // see if the matching wakeupOnCollisionEntry // condition exists 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)) { // Should not call collideEntryList.remove(i); // Otherwise wakeupOn for Entry case may call several // time at when initialize if collide if (target == null) { w.setTriggered(); } break; } } } } void addWakeupOnCollision(WakeupOnCollisionMovement w) { wakeupOnCollisionMovement.add(w); w.updateCollisionBounds(false); BHLeafInterface target = collide(w.behav.locale, w.accuracyMode, w.geometryAtoms, w.vwcBounds, w.boundingLeaf, w.armingNode, w); if (target != null) { w.setTarget(target); collideMovementList.add(w); } } void removeWakeupOnCollision(WakeupOnCollisionEntry wentry) { wakeupOnCollisionEntry.remove(wentry); // No need to remove collideEntry, it is used next time // when WakeupOnExitCollision is added to determine // whether to trigger it. } void removeWakeupOnCollision(WakeupOnCollisionExit wexit) { wakeupOnCollisionExit.remove(wexit); // No need to remove collideExit, it is used next time // when WakeupOnExitCollision is added to determine // whether to trigger it. } void removeWakeupOnCollision(WakeupOnCollisionMovement wmovement) { wakeupOnCollisionMovement.remove(wmovement); collideMovementList.remove(wmovement); // remove if exists } /** * This method test all wakeupOnCollision list and trigger the * condition if collision occurs. */ void processCollisionDetection() { int i, idx; BHLeafInterface target; // handle WakeupOnCollisionEntry WakeupOnCollisionEntry wentry; WakeupOnCollisionEntry wentryArr[] = (WakeupOnCollisionEntry []) wakeupOnCollisionEntry.toArray(); for (i = wakeupOnCollisionEntry.arraySize()-1; i >=0; i--) { wentry = wentryArr[i]; wentry.updateCollisionBounds(reEvaluateWakeupCollisionGAs); target = collide(wentry.behav.locale, wentry.accuracyMode, wentry.geometryAtoms, wentry.vwcBounds, wentry.boundingLeaf, wentry.armingNode, null); idx = collideEntryList.indexOf(wentry); if (target != null) { if (idx < 0) { collideEntryList.add(wentry); wentry.setTarget(target); wentry.setTriggered(); } } else { if (idx >= 0) { collideEntryList.remove(idx); } } } // handle WakeupOnCollisionMovement WakeupOnCollisionMovement wmove; WakeupOnCollisionMovement wmoveArr[] = (WakeupOnCollisionMovement []) wakeupOnCollisionMovement.toArray(); for (i = wakeupOnCollisionMovement.arraySize()-1; i >=0; i--) { wmove = wmoveArr[i]; wmove.updateCollisionBounds(reEvaluateWakeupCollisionGAs); target = collide(wmove.behav.locale, wmove.accuracyMode, wmove.geometryAtoms, wmove.vwcBounds, wmove.boundingLeaf, wmove.armingNode, wmove); idx = collideMovementList.indexOf(wmove); if (target != null) { if (idx < 0) { collideMovementList.add(wmove); wmove.setTarget(target); } else { if (!wmove.duplicateEvent) { wmove.setTriggered(); } } } else { if (idx >= 0) { collideMovementList.remove(idx); wmove.lastSrcBounds = null; wmove.lastDstBounds = null; } } } // Finally, handle WakeupOnCollisionExit WakeupOnCollisionExit wexit; WakeupOnCollisionExit wexitArr[] = (WakeupOnCollisionExit []) wakeupOnCollisionExit.toArray(); for (i = wakeupOnCollisionExit.arraySize()-1; i >=0; i--) { wexit = wexitArr[i]; wexit.updateCollisionBounds(reEvaluateWakeupCollisionGAs); target = collide(wexit.behav.locale, wexit.accuracyMode, wexit.geometryAtoms, wexit.vwcBounds, wexit.boundingLeaf, wexit.armingNode, null); idx = collideExitList.indexOf(wexit); if (target != null) { if (idx < 0) { collideExitList.add(wexit); wexit.setTarget(target); } } else { if (idx >= 0) { collideExitList.remove(idx); wexit.setTriggered(); } } } } /** * Check for duplicate WakeupOnCollisionMovement event. * We don't want to continue deliver event even though the * two colliding object did not move but this Geometry update * thread continue to run due to transform change in others * shape not in collision. */ void checkDuplicateEvent(WakeupOnCollisionMovement wmove, Bounds bound, BHLeafInterface hitNode) { Bounds hitBound; if ((wmove.lastSrcBounds != null) && wmove.lastSrcBounds.equals(bound)) { if (hitNode instanceof GeometryAtom) { hitBound = ((GeometryAtom) hitNode).source.vwcBounds; } else { hitBound = ((GroupRetained) hitNode).collisionVwcBounds; } if ((wmove.lastDstBounds != null) && wmove.lastDstBounds.equals(hitBound)) { wmove.duplicateEvent = true; } else { wmove.duplicateEvent = false; wmove.lastDstBounds = (Bounds) hitBound.clone(); } } else { wmove.duplicateEvent = false; wmove.lastSrcBounds = (Bounds) bound.clone(); } } /** * check if either the geomAtoms[] or * bound or boundingLeaf collide with BHTree. * Only one of geomAtoms, bound, boundingLeaf is non-null. * If accurancyMode is USE_GEOMETRY, object geometry is used, * otherwise object bounding box is used for collision * detection. * In case of GROUP & BOUND, the armingNode is used * to tell whether the colliding Group is itself or not. * Also in case GROUP, geomAtoms is non-null if USE_GEOMETRY. * If cond != null, it must be instanceof WakeupOnCollisionMovement */ BHLeafInterface collide(Locale locale, int accurancyMode, UnorderList geomAtoms, Bounds bound, BoundingLeafRetained boundingLeaf, NodeRetained armingNode, WakeupCriterion cond) { lock.readLock(); int idx = getBHTreeIndex(locale); if (idx < 0) { lock.readUnlock(); return null; } BHLeafInterface hitNode; if (geomAtoms != null) { synchronized (bhTreeArr[idx]) { if ((bound != null) && (armingNode instanceof GroupRetained)) { // Check Bound intersect first before process // to individual Shape3D geometryAtoms hitNode = bhTreeArr[idx].selectAny(bound, accurancyMode, (GroupRetained) armingNode); if (hitNode == null) { lock.readUnlock(); return null; } GeometryAtom galist[] = (GeometryAtom []) geomAtoms.toArray(false); hitNode = bhTreeArr[idx].selectAny(galist, geomAtoms.arraySize(), accurancyMode); if (hitNode != null) { lock.readUnlock(); if (cond != null) { checkDuplicateEvent((WakeupOnCollisionMovement) cond, bound, hitNode); } return hitNode; } } else { GeometryAtom ga = (GeometryAtom) geomAtoms.get(0); hitNode = bhTreeArr[idx].selectAny(ga, accurancyMode); if (hitNode != null) { lock.readUnlock(); if (cond != null) { checkDuplicateEvent((WakeupOnCollisionMovement) cond, ga.source.vwcBounds, hitNode); } return hitNode; } } } } else { if (bound == null) { if (boundingLeaf == null) { lock.readUnlock(); return null; } bound = boundingLeaf.transformedRegion; } if (bound == null) { lock.readUnlock(); return null; } if (armingNode instanceof GroupRetained) { synchronized (bhTreeArr[idx]) { hitNode = bhTreeArr[idx].selectAny(bound, accurancyMode, (GroupRetained) armingNode); lock.readUnlock(); if ((hitNode != null) && (cond != null)) { checkDuplicateEvent((WakeupOnCollisionMovement) cond, bound, hitNode); } return hitNode; } } else { synchronized (bhTreeArr[idx]) { hitNode = bhTreeArr[idx].selectAny(bound, accurancyMode, armingNode); lock.readUnlock(); if ((hitNode != null) && (cond != null)) { checkDuplicateEvent((WakeupOnCollisionMovement) cond, bound, hitNode); } return hitNode; } } } lock.readUnlock(); return null; } /** * This prevents wakeupCondition sent out message and set * conditionMet to true but the * BehaviorStructure/BehaviorScheduler is not fast enough to * process the message and reset conditionMet to false * when view deactivate/unregister. */ void resetConditionMet() { BehaviorStructure.resetConditionMet(wakeupOnCollisionEntry); BehaviorStructure.resetConditionMet(wakeupOnCollisionExit); BehaviorStructure.resetConditionMet(wakeupOnCollisionMovement); } /** * This processes a switch change. */ private void processSwitchChanged(J3dMessage m) { int i; UnorderList arrList; int size, treeIndex; Object[] nodes; LeafRetained leaf;/* is now a NOOP UpdateTargets targets = (UpdateTargets)m.args[0]; arrList = targets.targetList[Targets.GEO_TARGETS]; if (arrList != null) { size = arrList.size(); nodes = arrList.toArray(false); treeIndex = getBHTreeIndex(((LeafRetained)nodes[0]).locale); for (i=0; i<size; i++) { leaf = (LeafRetained)nodes[i]; } }*/ } void cleanup() { collideEntryList.clear(); collideExitList.clear(); collideMovementList.clear(); wakeupOnCollisionEntry.clear(); wakeupOnCollisionExit.clear(); wakeupOnCollisionMovement.clear(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -