📄 noderetained.java
字号:
/* * $RCSfile: NodeRetained.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.8 $ * $Date: 2007/04/20 00:54:41 $ * $State: Exp $ */package javax.media.j3d;import java.util.Vector;import java.util.Hashtable;import java.util.ArrayList;/** * The Node class provides an abstract class for all Group and Leaf * Nodes. It provides a common framework for constructing a Java 3D * scene graph, including bounding volumes and parent pointers. */abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId { // All the node types in the scene graph static final int BACKGROUND = 1; static final int CLIP = 2; static final int LINEARFOG = 3; static final int EXPONENTIALFOG = 4; static final int AMBIENTLIGHT = 5; static final int DIRECTIONALLIGHT = 6; static final int POINTLIGHT = 7; static final int SPOTLIGHT = 8; static final int LINK = 9; static final int MORPH = 10; static final int SHAPE = 11; static final int BACKGROUNDSOUND = 12; static final int POINTSOUND = 13; static final int CONESOUND = 14; static final int SOUNDSCAPE = 15; static final int VIEWPLATFORM = 16; static final int BEHAVIOR = 17; static final int SWITCH = 18; static final int BRANCHGROUP = 19; static final int ORDEREDGROUP = 20; static final int DECALGROUP = 21; static final int SHAREDGROUP = 22; static final int GROUP = 23; static final int TRANSFORMGROUP = 24; static final int BOUNDINGLEAF = 25; static final int MODELCLIP = 26; static final int ALTERNATEAPPEARANCE= 27; static final int ORIENTEDSHAPE3D = 28; static final int VIEWSPECIFICGROUP = 29; static final int NUMNODES = 29; // traverse flags static final int CONTAINS_VIEWPLATFORM = 0x1; /** * The universe that we are in */ VirtualUniverse universe = null; /** * The locale that this node is attatched to. This is only non-null * if this instance is directly linked into a locale. */ Locale locale = null; /** * The node's parent. */ NodeRetained parent = null; /** * The node's internal identifier. */ String nodeId = null; /** * An int that represents the nodes type. Used for quick if tests * in the traverser. */ int nodeType; // This keeps track of how many times this Node is refernced, refCount > 1 // if node is in a shared group int refCount = 0; /** * This is the index for the child, as seen by its parent. */ int childIndex = -1; /** * This boolean is true when the node is in a sharedGroup */ boolean inSharedGroup = false; /** * This indicates if the node is pickable. If this node is not * pickable then neither are any children */ boolean pickable = true; /** * The collidable setting; see getCollidable and setCollidable. */ boolean collidable = true; // A list of localToVworld transforms. If inSharedGroup is false, // then only localToVworld[0][] is valid. // Note: this contains reference to the actual transforms in the // TransformGroupRetained Transform3D localToVworld[][] = null; int localToVworldIndex[][] = null; static final int LAST_LOCAL_TO_VWORLD = 0; static final int CURRENT_LOCAL_TO_VWORLD = 1; // A parallel array to localToVworld. This is the keys for // localToVworld transforms in shared groups. HashKey localToVworldKeys[] = null; /** * This boolean is true when the geometric bounds for the node is * automatically updated */ boolean boundsAutoCompute = true; // "effective" bounds in local coordinate if boundsAutoCompute == F, // used for internal operations, not used if boundsAutoCompute == T Bounds localBounds; // Bounds set by the API Bounds apiBounds; protected Bounds cachedBounds=null; // Cached auto compute bounds, could we use localBounds ? /** * Each element, p, of branchGroupPaths is a list of BranchGroup from * root of the tree to this. * For BranchGroup under a non-shared group this size of * branchGroupPaths is always 1. Otherwise, the size is equal to * the number of possible paths to reach this node. * This variable is used to cached BranchGroup for fast picking. * For non BranchGroupRetained class this is a reference to * the previous BranchGroupRetained branchGroupPaths. */ ArrayList branchGroupPaths = new ArrayList(1); // background node whose geometry branch contains this node BackgroundRetained geometryBackground = null; // closest parent which is a TransformGroupRetained or sharedGroupRetained GroupRetained parentTransformLink = null; // closest parent which is a SwitchRetained or sharedGroupRetained GroupRetained parentSwitchLink = null; // static transform if a parent transform group is merged during compile. TransformGroupRetained staticTransform = null; // orderedId assigned by OrderedGroup parent Integer orderedId = null; // Id use for quick search. int nnuId; NodeRetained() { // Get a not necessary unique Id. nnuId = NnuIdManager.getId(); localBounds = new BoundingBox(); ((BoundingBox)localBounds).setUpper(-1.0, -1.0, -1.0); ((BoundingBox)localBounds).setLower( 1.0, 1.0, 1.0); } public int getId() { return nnuId; } public int equal(NnuId obj) { int keyId = obj.getId(); if(nnuId < keyId) { return -1; } else if(nnuId > keyId) { return 1; } else { // Found it! return 0; } } Bounds getLocalBounds(Bounds bounds) { return (Bounds)bounds.clone(); } /** * Sets the geometric bounds of a node. * @param bounds the bounding object for the node */ void setBounds(Bounds bounds) { apiBounds = bounds; if (source.isLive()) { if (!boundsAutoCompute) { if (bounds != null) { localBounds = getLocalBounds(bounds); if (staticTransform != null) { localBounds.transform(staticTransform.transform); } } else { if(localBounds != null) { localBounds.set((Bounds)null); } else { localBounds = new BoundingBox((Bounds)null); } } } } else { if (bounds != null) { localBounds = getLocalBounds(bounds); if (staticTransform != null) { localBounds.transform(staticTransform.transform); } } else { if(localBounds != null) { localBounds.set((Bounds)null); } else { localBounds = new BoundingBox((Bounds)null); } } } } /** * Gets the bounding object of a node. * @return the node's bounding object */ Bounds getEffectiveBounds() { Bounds b = null; if (localBounds != null && !localBounds.isEmpty()) { b = (Bounds) localBounds.clone(); if (staticTransform != null) { Transform3D invTransform = staticTransform.getInvTransform(); b.transform(invTransform); } } return b; } Bounds getBounds() { return apiBounds; } /** * ONLY needed for SHAPE, MORPH, and LINK node type. * Compute the combine bounds of bounds and its localBounds. */ void computeCombineBounds(Bounds bounds) { // Do nothing except for Group, Shape3D, Morph, and Link node. } /** * Sets the automatic calcuation of geometric bounds of a node. * @param autoCompute is a boolean value indicating if automatic calcuation * of bounds */ void setBoundsAutoCompute(boolean autoCompute) { if (this.boundsAutoCompute==autoCompute) { return; } this.boundsAutoCompute = autoCompute; dirtyBoundsCache(); } /** * Gets the auto Compute flag for the geometric bounds. * @return the node's auto Compute flag for the geometric bounding object */ boolean getBoundsAutoCompute() { return boundsAutoCompute; } /** * Replaces the specified parent by a new parent. * @param parent the new parent */ void setParent(NodeRetained parent) { this.parent = parent; } /** * Returns the parent of the node. * @return the parent. */ NodeRetained getParent() { return (NodeRetained)parent; } // Transform the input bound by the current LocalToVWorld void transformBounds(SceneGraphPath path, Bounds bound) { if (!((NodeRetained) path.item.retained).inSharedGroup) { bound.transform(getCurrentLocalToVworld()); } else { HashKey key = new HashKey(""); path.getHashKey(key); bound.transform(getCurrentLocalToVworld(key)); } } // Note : key will get modified in this method. private void computeLocalToVworld( NodeRetained caller, NodeRetained nodeR, HashKey key, Transform3D l2Vw) { int i; // To handle localToVworld under a SG. if(nodeR instanceof SharedGroupRetained) { // Get the immediate parent's id and remove last id from key. String nodeId = key.getLastNodeId(); SharedGroupRetained sgRetained = (SharedGroupRetained) nodeR; // Search for the right parent. for(i=0; i<sgRetained.parents.size(); i++) { if(nodeId.equals((String)(((NodeRetained) (sgRetained.parents.elementAt(i))).nodeId))) { // Found the right link. Now traverse upward. computeLocalToVworld(caller, (NodeRetained)(sgRetained.parents.elementAt(i)), key, l2Vw); return; } } // Problem ! throw new RuntimeException(J3dI18N.getString("NodeRetained4")); } else { NodeRetained nodeParentR =(NodeRetained)nodeR.getParent(); if(nodeParentR == null) { // Base case. It has to be a BG attached to a locale. if(((BranchGroupRetained)(nodeR)).locale != null) { l2Vw.setIdentity(); } else { throw new RuntimeException(J3dI18N.getString("NodeRetained5")); } } else { computeLocalToVworld(caller, (NodeRetained)nodeParentR, key, l2Vw); } } if((nodeR instanceof TransformGroupRetained) && (nodeR != caller)) { Transform3D t1 = new Transform3D(); ((TransformGroupRetained)(nodeR)).transform.getWithLock(t1); l2Vw.mul(t1); } else if ((nodeR == caller) && (staticTransform != null)) { l2Vw.mul(staticTransform.transform); } return; } /** * Compute the LocalToVworld of this node even though it is not live. We * assume the graph is attached at the origin of a locale */ void computeNonLiveLocalToVworld(Transform3D t, Node caller) { NodeRetained n = getParent(); if (n==null) t.setIdentity(); else n.computeNonLiveLocalToVworld(t, caller); if (this instanceof TransformGroupRetained && this.source!=caller) { Transform3D trans = new Transform3D(); ((TransformGroupRetained)this).getTransform(trans); t.mul(trans); } } /** * Get the localToVworld transform for a node. */ void getLocalToVworld(Transform3D t) { if (inSharedGroup) { throw new IllegalSharingException(J3dI18N.getString("NodeRetained0")); } // Lock the object while writing into t. if (localToVworld == null) { t.setIdentity(); } else { computeLocalToVworld(this, this, null, t); } } /** * Get the localToVworld transform for a node. */ void getLocalToVworld(SceneGraphPath path, Transform3D t) { HashKey key = new HashKey(""); if (inSharedGroup == false) { throw new IllegalSharingException(J3dI18N.getString("NodeRetained1")); } path.validate(key); computeLocalToVworld(this, this, key, t); } /** * Get the localToVworld transform for a node */ void getLocalToVworld(Transform3D t, HashKey key) { HashKey newKey = new HashKey(key); computeLocalToVworld(this, this, newKey, t); } /** * Get the Locale to which the node is attached */ Locale getLocale() { if (inSharedGroup) { throw new IllegalSharingException(J3dI18N.getString("NodeRetained0")); } return locale; } /** * Get the current localToVworld transform for a node */ Transform3D getCurrentLocalToVworld() { if (localToVworld != null) { return localToVworld[0][localToVworldIndex[0][CURRENT_LOCAL_TO_VWORLD]]; } else { return new Transform3D(); } } // this method expects that localToVworld is not null Transform3D getCurrentLocalToVworld(int index) { return localToVworld[index][localToVworldIndex[index][CURRENT_LOCAL_TO_VWORLD]]; } Transform3D getCurrentLocalToVworld(HashKey key) { if (localToVworld != null) { if (!inSharedGroup) { return localToVworld[0][localToVworldIndex[0][CURRENT_LOCAL_TO_VWORLD]]; } else { int i = key.equals(localToVworldKeys, 0, localToVworldKeys.length); if(i>= 0) { return localToVworld[i][localToVworldIndex[i][CURRENT_LOCAL_TO_VWORLD]]; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -