📄 scenegraphpath.java
字号:
/** * Returns a hash number based on the data values in this * object. Two different SceneGraphPath objects with identical data * values (ie, returns true for trans.equals(SceneGraphPath) ) will * return the same hash number. Two Paths with different data members * may return the same hash value, although this is not likely. * @return the integer hash value */ public int hashCode() { HashKey key = new HashKey(250); // NOTE: Needed to add interior != null because this method is called // by object.toString() when interior is null. if(interior != null && item != null) { for(int i=0; i<interior.length; i++) { key.append(LinkRetained.plus).append( item.toString() ); } } return( key.hashCode() + transform.hashCode() ); } /** * Determines whether two SceneGraphPath objects represent the same * path in the scene graph; either object might include a different * subset of internal nodes; only the internal link nodes, the Locale, * and the Node itself are compared. The paths are not validated for * correctness or uniqueness. * @param testPath the SceneGraphPath to be compared to this SceneGraphPath * @return true or false */ public final boolean isSamePath(SceneGraphPath testPath) { int count=0, i; if(testPath == null || testPath.item != this.item || root != testPath.root) return false; if(interior != null && testPath.interior != null) { for(i=0 ; i<interior.length ; i++) { if(interior[i] instanceof Link) { // found Link in this, now check for matching in testPath while(count < testPath.interior.length) { if(testPath.interior[count] instanceof Link) { if(testPath.interior[count] != interior[i]) { return false; } count++; break; } count++; // if true, this had an extra Link if(count == testPath.interior.length) return false; } } } // make sure testPath doesn't have any extra Links while(count < testPath.interior.length) { if(testPath.interior[count] instanceof Link) return false; count++; } } else if(interior != testPath.interior) // ==> they are not both null return false; return true; } /** * Returns a string representation of this object; * the string contains the class names of all Nodes in the SceneGraphPath, * the toString() method of any associated user data provided by * SceneGraphObject.getUserData(), and also prints out the transform, * if it is not null. * @return String representation of this object */ public String toString() { StringBuffer str = new StringBuffer(); Object obj; if(root == null && interior == null && item == null) return (super.toString()); if(root != null) str.append(root + " : "); if(interior != null) { for(int i=0; i<interior.length; i++) { str.append( interior[i].getClass().getName()); obj = interior[i].getUserData(); if(obj == null) str.append(" : "); else str.append(", " + obj + " : "); } } if(item != null) { // str.append( item + ", "+ item.getUserData() + "--"+intersectPoint ); str.append( item.getClass().getName() ); obj = item.getUserData(); if(obj != null) str.append(", " + obj); try { if (item.getClass().getName().equals("javax.media.j3d.Shape3D")) str.append( ((Shape3D)item).getGeometry() ); } catch( CapabilityNotSetException e) {} } str.append("\n" + "LocalToVworld Transform:\n" + transform); return new String(str); } /** * Determine if this SceneGraphPath is unique and valid * The graph don't have to be live for this checking. * Set Locale when it is null. * Only the essential link node which led to the Locale * is validated. */ boolean validate() { NodeRetained node = (NodeRetained) item.retained; Locale locale = node.locale; if (root != null) { if (item.isLive()) { if (locale != root) { return false; } } } else { root = locale; } int idx = (interior == null ? 0: interior.length); do { if (node instanceof SharedGroupRetained) { if (interior == null) return false; while (--idx > 0) { if (((SharedGroupRetained) node).parents.contains(interior[idx].retained)) { break; } } if (idx < 0) { return false; } node = (NodeRetained) interior[idx].retained; } else { node = node.parent; } } while (node != null); return true; } // return key of this path or null is not in SharedGroup void getHashKey(HashKey key) { if (interior != null) { key.reset(); key.append(root.nodeId); for(int i=0; i<interior.length; i++) { Node node = interior[i]; if (!node.isLive()) { throw new RuntimeException(J3dI18N.getString("SceneGraphPath3")); } NodeRetained nodeR = (NodeRetained) node.retained; if (nodeR.nodeType == NodeRetained.LINK) { key.append("+").append(nodeR.nodeId); } } } } /** * Determines whether this SceneGraphPath is unique and valid. The * verification determines that all of the nodes are live, that the * specified path is unique, that the correct Locale is specified, and * that there is a Node specified. */ boolean validate(HashKey key) { int i; // verify that there is at least a Locale and Node specified if( root == null ) throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath2")); if( item == null ) throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath10")); // verify liveness if( !item.isLive() ) throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath3")); try { getHashKey(key); } catch (RuntimeException ex) { throw new IllegalArgumentException(ex.getMessage()); } // The rest of the code verifies uniqueness; it traverses the retained // hierarchy of the scene graph. This could be problematic later in // when certain compile mode optimizations are added. */ NodeRetained bottomNR, currentNR, nextNR=null; Node currentNode; int count = 0; // Need to traverse the retained hierarchy on a live scene graph // from bottom to top // // bottomNR = last verified node; as nodes are verified, bottomNR // moves up the scen graph // nextNR = Next node that the user has specified after bottomNR // currentNR = current node; is changing as it covers all the // nodes from bottomNR to nextNR // If the parent of a NodeRetained is null, we know that the parent // is either a BranchGroupRetained at the top of a scene graph or // it is a SharedGroupRetained, potentially with multiple parents. bottomNR = (NodeRetained)(item.retained); if(interior != null) { for(i=interior.length-1; i >=0 ; i--) { nextNR = (NodeRetained)(interior[i].retained); currentNR = bottomNR.parent; if(currentNR == null && bottomNR instanceof SharedGroupRetained) { if(((SharedGroupRetained)(bottomNR)).parents.contains(nextNR) ) currentNR = nextNR; else throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath5")); } while(currentNR != nextNR) { if(currentNR == null) { throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath11")); } if(currentNR instanceof SharedGroupRetained) { if(((SharedGroupRetained) (currentNR)).parents.contains(nextNR) ) currentNR = nextNR; else throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath5")); } else { currentNR = currentNR.parent; } } bottomNR = currentNR; } } // Now go from bottomNR to Locale currentNR = bottomNR.parent; if(currentNR == null && bottomNR instanceof SharedGroupRetained) { throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath5")); } while(currentNR != null) { if(currentNR instanceof LinkRetained) { throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath5")); } bottomNR = currentNR; currentNR = currentNR.parent; if(currentNR == null && bottomNR instanceof SharedGroupRetained) { throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath5")); } } // get the real BranchGroup from the BranchGroupRetained currentNode = (Node)(bottomNR.source); // now bottomNR should be a BranchGroup -- should try an assert here if(!root.branchGroups.contains(currentNode)) { throw new IllegalArgumentException(J3dI18N.getString("SceneGraphPath9")); } return true; } /** * Returns the distance from the intersectPoint for item and * origin. */ double getDistanceFrom( Point3d origin ) { return intersectPoint.distance(origin); } /** * Returns the distance of the pick */ double getDistance() { return pickDistance; } final void setIntersectPoint( Point3d point ) { intersectPoint.set(point); } final void setIntersectPointDis( Point4d pickLocation ) { // System.err.println( "setIntersectPointDis pickLocation= "+pickLocation); intersectPoint.x = pickLocation.x; intersectPoint.y = pickLocation.y; intersectPoint.z = pickLocation.z; pickDistance = pickLocation.w; } final Point3d getIntersectPoint() { return intersectPoint; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -