📄 pickobject.java
字号:
/** * Returns a reference to any item that is Pickable below the specified * <code>BranchGroup</code> (specified in the PickObject constructor) which * intersects with the ray that starts at the viewer * position and points into the scene in the direction of (xpos, ypos) in * window space. * * @param xpos The value along the x-axis. * @param ypos The value along the y-axis. * @param flag Specifys picking by Geometry or Bounds. * @return A SceneGraphPath of an object that was picked. This is not * guarenteed to return the same result for multiple picks * If no pickable object is found <code>null</code> is returned.. * * @see SceneGraphPath */ public SceneGraphPath pickAny(int xpos, int ypos, int flag) { if(flag == USE_BOUNDS) { return pickAny(xpos, ypos); } else if(flag == USE_GEOMETRY) { return pickGeomAny(xpos, ypos); } else return null; } /** * Returns a reference to the item that is closest to the viewer and is * Pickable below the <code>BranchGroup</code> (specified in the PickObject * constructor) which intersects with the ray that starts at * the viewer position and points into the scene in the direction of * (xpos, ypos) in the window space. * * @param xpos The value along the x-axis. * @param ypos The value along the y-axis. * @param flag Specifys picking by Geometry or Bounds. * @return A SceneGraphPath which contains the closest pickable object. * If no pickable object is found, <code>null</code> is returned. * * @see SceneGraphPath */ public SceneGraphPath pickClosest(int xpos, int ypos, int flag) { if(flag == USE_BOUNDS) { return pickClosest(xpos, ypos); } else if(flag == USE_GEOMETRY) { return pickGeomClosest(xpos, ypos); } else return null; } private SceneGraphPath[] pickGeomAll(int xpos, int ypos) { Node obj; int i, cnt=0; pickRay = (PickRay) generatePickRay(xpos, ypos); sceneGraphPathArr = pickRoot.pickAll(pickRay); if(sceneGraphPathArr == null) return null; boolean found[] = new boolean[sceneGraphPathArr.length]; for(i=0; i<sceneGraphPathArr.length; i++) { obj = sceneGraphPathArr[i].getObject(); if(obj instanceof Shape3D) { found[i] = ((Shape3D) obj).intersect(sceneGraphPathArr[i], (PickShape) pickRay); } else if(obj instanceof Morph) { found[i] = ((Morph) obj).intersect(sceneGraphPathArr[i], (PickShape) pickRay); } if(found[i] == true) cnt++; } if(cnt == 0) return null; SceneGraphPath newSceneGraphPathArr[] = new SceneGraphPath[cnt]; cnt = 0; // reset for reuse. for(i=0; i<sceneGraphPathArr.length; i++) { if(found[i] == true) newSceneGraphPathArr[cnt++] = sceneGraphPathArr[i]; } return newSceneGraphPathArr; } private double distance[]; private SceneGraphPath[] pickGeomAllSorted(int xpos, int ypos) { Node obj; int i, cnt=0; double dist[] = new double[1]; // System.out.print("In pickGeomAllSorted\n"); pickRay = (PickRay) generatePickRay(xpos, ypos); sceneGraphPathArr = pickRoot.pickAll(pickRay); if(sceneGraphPathArr == null) return null; boolean found[] = new boolean[sceneGraphPathArr.length]; double distArr[] = new double[sceneGraphPathArr.length]; for(i=0; i<sceneGraphPathArr.length; i++) { obj = sceneGraphPathArr[i].getObject(); if(obj instanceof Shape3D) { found[i] = ((Shape3D) obj).intersect(sceneGraphPathArr[i], pickRay, dist); distArr[i] = dist[0]; } else if(obj instanceof Morph) { found[i] = ((Morph) obj).intersect(sceneGraphPathArr[i], pickRay, dist); distArr[i] = dist[0]; } if(found[i] == true) cnt++; } if(cnt == 0) return null; SceneGraphPath newSceneGraphPathArr[] = new SceneGraphPath[cnt]; distance = new double[cnt]; cnt = 0; // reset for reuse. for(i=0; i<sceneGraphPathArr.length; i++) { if(found[i] == true) { newSceneGraphPathArr[cnt] = sceneGraphPathArr[i]; distance[cnt++] = distArr[i]; } } return sort(newSceneGraphPathArr); } private SceneGraphPath pickGeomClosest(int xpos, int ypos) { SceneGraphPath sgpArr[] = pickGeomAllSorted(xpos, ypos); if (sgpArr == null) return null; return sgpArr[0]; } private SceneGraphPath pickGeomAny(int xpos, int ypos) { Node obj; int i; pickRay = (PickRay) generatePickRay(xpos, ypos); sceneGraphPathArr = pickRoot.pickAll(pickRay); for(i=0; i<sceneGraphPathArr.length; i++) { obj = sceneGraphPathArr[i].getObject(); if(obj instanceof Shape3D) { if(((Shape3D) obj).intersect(sceneGraphPathArr[i],(PickShape) pickRay)) return sceneGraphPathArr[i]; } else if(obj instanceof Morph) { if(((Morph) obj).intersect(sceneGraphPathArr[i],(PickShape) pickRay)) return sceneGraphPathArr[i]; } } return null; } /** * Sort the elements in sgpArr and * return the sorted list in SceneGraphPath * * Sorts on the distance but also adjusts an array of positions * this allows the sort to operate on small data elements rather * than the possibly large SceneGraphPath * * Initial implementation is a Quick Sort */ private int position[]; private SceneGraphPath[] sort(SceneGraphPath sgpArr[]) { if (sgpArr == null) return null; SceneGraphPath sorted[] = new SceneGraphPath[sgpArr.length]; position = new int[sgpArr.length]; for(int i=0; i<sgpArr.length; i++) { position[i]=i; } /* System.out.println("Before Sort :"); for(int i=0; i<distance.length; i++) { System.out.println("pos " + position[i] +" dist "+ distance[i] + " sgp "+ sgpArr[i]); } */ quicksort( 0, distance.length-1 ); for(int i=0; i<distance.length; i++) { sorted[i]= sgpArr[position[i]]; } /* System.out.println("\nAfter Sort :"); for(int i=0; i<distance.length; i++) { System.out.println("pos " + position[i] +" dist "+ distance[i] + " sorted sgp "+ sorted[i]); } */ return sorted; } private final void quicksort( int l, int r ) { int p,i,j; double tmp,k; i = l; j = r; k = distance[(l+r) / 2]; do { while (distance[i]<k) i++; while (k<distance[j]) j--; if (i<=j) { tmp = distance[i]; distance[i] =distance[j]; distance[j] = tmp; p=position[i]; position[i]=position[j]; position[j]=p; i++; j--; } } while (i<=j); if (l<j) quicksort(l,j); if (l<r) quicksort(i,r); } /** * Returns a reference to a Pickable Node that * is of the specified type * that is contained in the specified SceneGraphPath. * If more than one node of the same type is encountered, the node * closest to the terminal node of SceneGraphPath will be returned. * * @param sgPath the SceneGraphPath to be traversed. * @param flags the Node types interested in picking. * @return the first occurrence of the specified Node type * starting from the terminal node of SceneGraphPath. * If no pickable object is found of the specifed types, * <code>null</code> is returned. */ public Node pickNode(SceneGraphPath sgPath, int flags) { if (sgPath != null) { Node pickedNode = sgPath.getObject(); if ((pickedNode instanceof Shape3D) && ((flags & SHAPE3D) != 0)){ if (debug) System.out.println("Shape3D found"); return pickedNode; } else if ((pickedNode instanceof Morph) && ((flags & MORPH) != 0)){ if (debug) System.out.println("Morph found"); return pickedNode; } else { for (int j=sgPath.nodeCount()-1; j>=0; j--){ pickedNode = sgPath.getNode(j); if (debug) System.out.println("looking at node " + pickedNode); if ((pickedNode instanceof Primitive) && ((flags & PRIMITIVE) != 0)){ if (debug) System.out.println("Primitive found"); return pickedNode; } else if ((pickedNode instanceof Link) && ((flags & LINK) != 0)){ if (debug) System.out.println("Link found"); return pickedNode; } else if ((pickedNode instanceof Switch) && ((flags & SWITCH) != 0)){ if (debug) System.out.println("Switch found"); return pickedNode; } else if ((pickedNode instanceof TransformGroup) && ((flags & TRANSFORM_GROUP) != 0)){ if (debug) System.out.println("xform group found"); return pickedNode; } else if ((pickedNode instanceof BranchGroup) && ((flags & BRANCH_GROUP) != 0)){ if (debug) System.out.println("Branch group found"); return pickedNode; } else if ((pickedNode instanceof Group) && ((flags & GROUP) != 0)){ if (debug) System.out.println("Group found"); return pickedNode; } } if (pickedNode == null) if (debug) System.out.println("ERROR: null SceneGraphPath"); } } return null; } /** * Returns a reference to a Pickable Node that * is of the specified type * that is contained in the specified SceneGraphPath. * The Node returned is the nth <code>occurrence</code> * of a Node that is of the specified type. * * @param sgPath the SceneGraphPath to be traversed. * @param flags the Node types interested. * @param occurrence the occurrence of a Node that * matches the specified type to return. An <code>occurrence</code> of * 1 means to return the first occurrence of that object type (the object * closest to the Locale). * @return the nth <code>occurrence</code> of a Node * of type <code>flags</code>, starting from the Locale. If no pickable object is * found, <code>null</code> is returned. */ public Node pickNode(SceneGraphPath sgPath, int flags, int occurrence) { int curCnt=0; if (sgPath != null) { Node pickedNode = sgPath.getObject(); // Shape3D and Morph are leaf nodes and have no children. It doesn't // make sense to do occurrence check here. We'll just return it for now. if ((pickedNode instanceof Shape3D) && ((flags & SHAPE3D) != 0)){ if (debug) System.out.println("Shape3D found"); return pickedNode; } else if ((pickedNode instanceof Morph) && ((flags & MORPH) != 0)){ if (debug) System.out.println("Morph found"); return pickedNode; } else { for (int j = 0; j < sgPath.nodeCount(); j++){ pickedNode = sgPath.getNode(j); if (debug) System.out.println("looking at node " + pickedNode); if ((pickedNode instanceof Group) && ((flags & GROUP) != 0)){ if (debug) System.out.println("Group found"); curCnt++; if(curCnt == occurrence) return pickedNode; } else if ((pickedNode instanceof BranchGroup) && ((flags & BRANCH_GROUP) != 0)){ if (debug) System.out.println("Branch group found"); curCnt++; if(curCnt == occurrence) return pickedNode; } else if ((pickedNode instanceof TransformGroup) && ((flags & TRANSFORM_GROUP) != 0)){ if (debug) System.out.println("xform group found"); curCnt++; if(curCnt == occurrence) return pickedNode; } else if ((pickedNode instanceof Primitive) && ((flags & PRIMITIVE) != 0)){ if (debug) System.out.println("Primitive found"); curCnt++; if(curCnt == occurrence) return pickedNode; } else if ((pickedNode instanceof Link) && ((flags & LINK) != 0)){ if (debug) System.out.println("Link found"); curCnt++; if(curCnt == occurrence) return pickedNode; } } if (pickedNode == null) if (debug) System.out.println("ERROR: null SceneGraphPath"); } } return null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -