📄 wakeuponcollisionentry.java
字号:
throws IllegalArgumentException { if ((speedHint != USE_GEOMETRY) && (speedHint != USE_BOUNDS)) { throw new IllegalArgumentException(J3dI18N.getString(s)); } } /** * This is a callback from BehaviorStructure. It is * used to add wakeupCondition to behavior structure. */ void addBehaviorCondition(BehaviorStructure bs) { switch (nodeType) { case SHAPE: // Use geometryAtoms[].collisionBounds case ORIENTEDSHAPE3D: if (!armingNode.source.isLive()) { return; } if (geometryAtoms == null) { geometryAtoms = new UnorderList(1, GeometryAtom.class); } Shape3DRetained shape = (Shape3DRetained) armingNode; geometryAtoms.add(Shape3DRetained.getGeomAtom(shape.getMirrorShape(armingPath))); break; case MORPH: // Use geometryAtoms[].collisionBounds if (!armingNode.source.isLive()) { return; } if (geometryAtoms == null) { geometryAtoms = new UnorderList(1, GeometryAtom.class); } MorphRetained morph = (MorphRetained) armingNode; geometryAtoms.add(Shape3DRetained.getGeomAtom(morph.getMirrorShape(armingPath))); break; case BOUNDINGLEAF: // use BoundingLeaf.transformedRegion if (!armingNode.source.isLive()) { return; } this.boundingLeaf = ((BoundingLeafRetained) armingNode).mirrorBoundingLeaf; break; case BOUND: // use this.vwcBounds vwcBounds = (Bounds) armingBounds.clone(); this.armingNode = behav; break; case GROUP: if (!armingNode.source.isLive()) { return; } if (accuracyMode == USE_GEOMETRY) { if (geometryAtoms == null) { geometryAtoms = new UnorderList(1, GeometryAtom.class); } ((GroupRetained) armingNode).searchGeometryAtoms(geometryAtoms); } // else use this.vwcBounds default: } behav.universe.geometryStructure.addWakeupOnCollision(this); } /** * This is a callback from BehaviorStructure. It is * used to remove wakeupCondition from behavior structure. */ void removeBehaviorCondition(BehaviorStructure bs) { vwcBounds = null; if (geometryAtoms != null) { geometryAtoms.clear(); } boundingLeaf = null; behav.universe.geometryStructure.removeWakeupOnCollision(this); } // Set collidingPath & collidingBounds void setTarget(BHLeafInterface leaf) { SceneGraphPath path; Bounds bound; if (leaf instanceof GeometryAtom) { // Find the triggered Path & Bounds for this geometry Atom GeometryAtom geomAtom = (GeometryAtom) leaf; Shape3DRetained shape = geomAtom.source; path = getSceneGraphPath(shape.sourceNode, shape.key, shape.getCurrentLocalToVworld(0)); bound = getTriggeringBounds(shape); } else { // Find the triggered Path & Bounds for this alternative // collision target GroupRetained group = (GroupRetained) leaf; path = getSceneGraphPath(group); bound = getTriggeringBounds(group); } if (path != null) { // colliding path may be null when branch detach before // user behavior retrieve the previous colliding path collidingPath = path; collidingBounds = bound; } } // Invoke from GeometryStructure to update vwcBounds of GROUP void updateCollisionBounds(boolean reEvaluateGAs){ if (nodeType == GROUP) { GroupRetained group = (GroupRetained) armingNode; if (group.collisionBound != null) { vwcBounds = (Bounds) group.collisionBound.clone(); } else { // this may involve recursive tree traverse if // BoundsAutoCompute is true, we can't avoid // since the bound under it may change by transform vwcBounds = group.getEffectiveBounds(); } group.transformBounds(armingPath, vwcBounds); } else if (nodeType == BOUND) { vwcBounds.transform(armingBounds, behav.getCurrentLocalToVworld()); } if (reEvaluateGAs && (nodeType == GROUP) && (accuracyMode == USE_GEOMETRY)) { geometryAtoms.clear(); ((GroupRetained) armingNode).searchGeometryAtoms(geometryAtoms); } } /** * Return the TriggeringBounds for node */ static Bounds getTriggeringBounds(Shape3DRetained mirrorShape) { NodeRetained node = mirrorShape.sourceNode; if (node instanceof Shape3DRetained) { Shape3DRetained shape = (Shape3DRetained) node; if (shape.collisionBound == null) { // TODO: get bounds by copy return shape.getEffectiveBounds(); } return shape.collisionBound; } MorphRetained morph = (MorphRetained) node; if (morph.collisionBound == null) { // TODO: get bounds by copy return morph.getEffectiveBounds(); } return morph.collisionBound; } /** * Return the TriggeringBounds for node */ static Bounds getTriggeringBounds(GroupRetained group) { if (group.collisionBound == null) { // TODO: get bounds by copy return group.getEffectiveBounds(); } return group.collisionBound; } static SceneGraphPath getSceneGraphPath(GroupRetained group) { // Find the transform base on the key Transform3D transform = null; GroupRetained srcGroup = group.sourceNode; synchronized (srcGroup.universe.sceneGraphLock) { if (group.key == null) { transform = srcGroup.getCurrentLocalToVworld(); } else { HashKey keys[] = srcGroup.localToVworldKeys; if (keys == null) { // the branch is already detach when // Collision got this message return null; } transform = srcGroup.getCurrentLocalToVworld(group.key); } return getSceneGraphPath(srcGroup, group.key, transform); } } /** * return the SceneGraphPath of the geomAtom. * Find the alternative Collision target closest to the locale. */ static SceneGraphPath getSceneGraphPath(NodeRetained startNode, HashKey key, Transform3D transform) { synchronized (startNode.universe.sceneGraphLock) { NodeRetained target = startNode; UnorderList path = new UnorderList(5, Node.class); NodeRetained nodeR = target; Locale locale = nodeR.locale; String nodeId; Vector parents; NodeRetained linkR; if (nodeR.inSharedGroup) { // getlastNodeId() will destroy this key if (key != null) { key = new HashKey(key); } else { key = new HashKey(startNode.localToVworldKeys[0]); } } do { if (nodeR.source.getCapability(Node.ENABLE_COLLISION_REPORTING)){ path.add(nodeR.source); } if (nodeR instanceof SharedGroupRetained) { // retrieve the last node ID nodeId = key.getLastNodeId(); parents = ((SharedGroupRetained) nodeR).parents; NodeRetained prevNodeR = nodeR; for(int i=parents.size()-1; i >=0; i--) { linkR = (NodeRetained) parents.elementAt(i); if (linkR.nodeId.equals(nodeId)) { nodeR = linkR; break; } } if (nodeR == prevNodeR) { // the branch is already detach when // Collision got this message return null; } } else if ((nodeR instanceof GroupRetained) && ((GroupRetained) nodeR).collisionTarget) { // we need to find the collision target closest to the // root of tree target = nodeR; if (key == null) { transform = nodeR.getCurrentLocalToVworld(null); } else { transform = nodeR.getCurrentLocalToVworld(key); } } nodeR = nodeR.parent; } while (nodeR != null); // reach Locale Node nodes[]; if (target == startNode) { // in most case nodes = (Node []) path.toArray(false); } else { // alternativeCollisionTarget is set nodes = (Node []) path.toArray(target); } SceneGraphPath sgpath = new SceneGraphPath(locale, nodes, (Node) target.source); sgpath.setTransform(transform); return sgpath; } } void setTriggered(){ // if path not set, probably the branch is just detach. if (collidingPath != null) { super.setTriggered(); } } /** * Perform task in addBehaviorCondition() that has to be * set every time the condition met. */ void resetBehaviorCondition(BehaviorStructure bs) { // The reference geometryAtom will not change once // Shape3D create so there is no need to set this. }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -