aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/Locale.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/javax/media/j3d/Locale.java')
-rw-r--r--src/javax/media/j3d/Locale.java1088
1 files changed, 1088 insertions, 0 deletions
diff --git a/src/javax/media/j3d/Locale.java b/src/javax/media/j3d/Locale.java
new file mode 100644
index 0000000..4da6c4a
--- /dev/null
+++ b/src/javax/media/j3d/Locale.java
@@ -0,0 +1,1088 @@
+/*
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package javax.media.j3d;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * A Locale object defines a high-resolution position within a
+ * VirtualUniverse, and serves as a container for a collection of
+ * BranchGroup-rooted subgraphs (branch graphs), at that position.
+ * Objects within a Locale are defined using standard double-precision
+ * coordinates, relative to the origin of the Locale. This origin
+ * defines the Virtual World coordinate system for that Locale.
+ * <p>
+ * A Locale object defines methods to set and get its high-resolution
+ * coordinates, and methods to add, remove, and enumerate the branch
+ * graphs.
+ *
+ * <p>
+ * For more information, see the
+ * <a href="doc-files/intro.html">Introduction to the Java 3D API</a> and
+ * <a href="doc-files/VirtualUniverse.html">Scene Graph Superstructure</a>
+ * documents.
+ *
+ * @see VirtualUniverse
+ * @see HiResCoord
+ * @see BranchGroup
+ */
+
+public class Locale extends Object {
+
+ /**
+ * The virtual universe that this Locale object is contained within.
+ */
+ VirtualUniverse universe;
+
+ /**
+ * The high resolution coordinate associated with this Locale object.
+ */
+ HiResCoord hiRes;
+
+/**
+ * List of BranchGroup objects included in this Locale
+ */
+Vector<BranchGroup> branchGroups = new Vector<BranchGroup>();
+
+ // locale's identifier
+ String nodeId = null;
+
+ /**
+ * Constructs and initializes a new high resolution Locale object
+ * located at (0, 0, 0).
+ * @param universe the virtual universe that will contain this
+ * Locale object
+ */
+ public Locale(VirtualUniverse universe) {
+ this.universe = universe;
+ this.universe.addLocale(this);
+ this.hiRes = new HiResCoord();
+ nodeId = universe.getNodeId();
+ }
+
+ /**
+ * Constructs and initializes a new high resolution Locale object
+ * from the parameters provided.
+ * @param universe the virtual universe that will contain this
+ * Locale object
+ * @param x an eight element array specifying the x position
+ * @param y an eight element array specifying the y position
+ * @param z an eight element array specifying the z position
+ */
+ public Locale(VirtualUniverse universe, int[] x, int[] y, int[] z) {
+ this.universe = universe;
+ this.universe.addLocale(this);
+ this.hiRes = new HiResCoord(x, y, z);
+ nodeId = universe.getNodeId();
+ }
+
+ /**
+ * Constructs and initializes a new high resolution Locale object
+ * at the location specified by the HiResCoord argument.
+ * @param universe the virtual universe that will contain this
+ * Locale object
+ * @param hiRes the HiRes coordinate to use in creating this Locale
+ */
+ public Locale(VirtualUniverse universe, HiResCoord hiRes) {
+ this.universe = universe;
+ this.universe.addLocale(this);
+ this.hiRes = new HiResCoord(hiRes);
+ nodeId = universe.getNodeId();
+ }
+
+ /**
+ * Retrieves the virtual universe within which this Locale object
+ * is contained. A null reference indicates that this
+ * Locale has been removed from its VirtualUniverse.
+ * @return the virtual universe within which this Locale object
+ * is contained.
+ */
+ public VirtualUniverse getVirtualUniverse() {
+ return universe;
+ }
+
+ /**
+ * Sets the HiRes coordinate of this Locale to the location
+ * specified by the parameters provided.
+ * @param x an eight element array specifying the x position
+ * @param y an eight element array specifying the y position
+ * @param z an eight element array specifying the z position
+ */
+ public void setHiRes(int[] x, int[] y, int[] z) {
+ this.hiRes.setHiResCoord(x, y, z);
+ }
+
+ /**
+ * Sets the HiRes coordinate of this Locale
+ * to the location specified by the HiRes argument.
+ * @param hiRes the HiRes coordinate specifying this node's new location
+ */
+ public void setHiRes(HiResCoord hiRes) {
+ this.hiRes.setHiResCoord(hiRes);
+ }
+
+ /**
+ * Returns this node's HiResCoord.
+ * @param hiRes a HiResCoord object that will receive the
+ * HiRes coordinate of this Locale node
+ */
+ public void getHiRes(HiResCoord hiRes) {
+ this.hiRes.getHiResCoord(hiRes);
+ }
+
+ /**
+ * Add a new branch graph rooted at BranchGroup to
+ * the list of branch graphs.
+ * @param branchGroup root of the branch graph to be added
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ * @exception MultipleParentException if the specified BranchGroup node
+ * is already live.
+ */
+ public void addBranchGraph(BranchGroup branchGroup){
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ // if the BranchGroup already has a parent, or has already been
+ // added to a locale, throw MultipleParentException
+ if ((((BranchGroupRetained)branchGroup.retained).parent != null) ||
+ (branchGroup.isLive())) {
+ throw new MultipleParentException(J3dI18N.getString("Locale0"));
+ }
+
+ universe.notifyStructureChangeListeners(true, this, branchGroup);
+ universe.resetWaitMCFlag();
+ synchronized (universe.sceneGraphLock) {
+ doAddBranchGraph(branchGroup);
+ universe.setLiveState.reset(this);
+ }
+ universe.waitForMC();
+ }
+
+ // The method that does the work once the lock is acquired.
+ void doAddBranchGraph(BranchGroup branchGroup) {
+ BranchGroupRetained bgr = (BranchGroupRetained)branchGroup.retained;
+ J3dMessage createMessage;
+ SetLiveState s = universe.setLiveState;
+
+ // bgr.setLocale(this);
+
+ // addElement needs to precede setLive or else any liveness checks
+ // in the initialize() call of a user behavior (ie, calling collision
+ // or picking constructor with a SceneGraphPath) will fail
+ // when SceneGraphPath.validate() attempts to verify that
+ // the proper Locale is associated with that SceneGraphPath
+ bgr.attachedToLocale = true;
+ branchGroups.addElement(branchGroup);
+ s.reset(this);
+ s.currentTransforms[0] = new Transform3D[2];
+ s.currentTransforms[0][0] = new Transform3D();
+ s.currentTransforms[0][1] = new Transform3D();
+ s.currentTransformsIndex[0] = new int[2];
+ s.currentTransformsIndex[0][0] = 0;
+ s.currentTransformsIndex[0][1] = 0;
+
+ s.localToVworld = s.currentTransforms;
+ s.localToVworldIndex = s.currentTransformsIndex;
+
+ s.branchGroupPaths = new ArrayList<BranchGroupRetained[]>();
+ s.branchGroupPaths.add(new BranchGroupRetained[0]);
+
+ s.orderedPaths = new ArrayList<OrderedPath>(1);
+ s.orderedPaths.add(new OrderedPath());
+
+ s.switchStates = new ArrayList<SwitchState>(1);
+ s.switchStates.add(new SwitchState(false));
+
+ bgr.setLive(s);
+
+ createMessage = new J3dMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ createMessage.type = J3dMessage.ORDERED_GROUP_INSERTED;
+ createMessage.universe = universe;
+ createMessage.args[0] = s.ogList.toArray();
+ createMessage.args[1] = s.ogChildIdList.toArray();
+ createMessage.args[2] = s.ogOrderedIdList.toArray();
+ createMessage.args[3] = s.ogCIOList.toArray();
+ createMessage.args[4] = s.ogCIOTableList.toArray();
+
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ createMessage = new J3dMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ createMessage.type = J3dMessage.VIEWSPECIFICGROUP_INIT;
+ createMessage.universe = universe;
+ createMessage.args[0] = s.changedViewGroup;
+ createMessage.args[1] = s.changedViewList;
+ createMessage.args[2] = s.keyList;
+ VirtualUniverse.mc.processMessage(createMessage);
+
+
+ createMessage = new J3dMessage();
+ createMessage.threads = s.notifyThreads;
+ createMessage.type = J3dMessage.INSERT_NODES;
+ createMessage.universe = universe;
+ createMessage.args[0] = s.nodeList.toArray();
+ createMessage.args[1] = null;
+ createMessage.args[2] = null;
+ if (s.viewScopedNodeList != null) {
+ createMessage.args[3] = s.viewScopedNodeList;
+ createMessage.args[4] = s.scopedNodesViewList;
+ }
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ int sz = s.behaviorNodes.size();
+ for (int i=0; i< sz; i++) {
+ BehaviorRetained b = s.behaviorNodes.get(i);
+ b.executeInitialize();
+ }
+
+ createMessage = new J3dMessage();
+ createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
+ createMessage.type = J3dMessage.BEHAVIOR_ACTIVATE;
+ createMessage.universe = universe;
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ // Free up memory.
+ s.reset(null);
+ }
+
+ /**
+ * Removes a branch graph rooted at BranchGroup from
+ * the list of branch graphs.
+ * @param branchGroup root of the branch graph to be removed
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ * @exception CapabilityNotSetException if the ALLOW_DETACH capability is
+ * not set in the specified BranchGroup node.
+ */
+ public void removeBranchGraph(BranchGroup branchGroup){
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ if (! branchGroup.getCapability(BranchGroup.ALLOW_DETACH)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("Locale1"));
+ }
+ universe.resetWaitMCFlag();
+ synchronized (universe.sceneGraphLock) {
+ doRemoveBranchGraph(branchGroup, null, 0);
+ universe.setLiveState.reset(this);
+ }
+ universe.waitForMC();
+ }
+
+
+ // Method to remove all branch graphs from this Locale and remove
+ // this Locale from the VirtualUniverse
+ void removeFromUniverse() {
+ if (branchGroups.size() > 0) {
+ universe.resetWaitMCFlag();
+ synchronized (universe.sceneGraphLock) {
+ // Make a copy of the branchGroups list so that we can safely
+ // iterate over it.
+ Object[] bg = branchGroups.toArray();
+ for (int i = 0; i < bg.length; i++) {
+ doRemoveBranchGraph((BranchGroup)bg[i], null, 0);
+ }
+ }
+ // Put after sceneGraphLock to prevent deadlock
+ universe.waitForMC();
+ }
+
+ // free nodeId
+ if (nodeId != null) {
+ universe.nodeIdFreeList.addElement(nodeId);
+ nodeId = null;
+ }
+
+ // Set universe pointer to null, indicating that this Locale
+ // has been removed from its universe
+ universe = null;
+ }
+
+
+ // The method that does the work once the lock is acquired.
+ void doRemoveBranchGraph(BranchGroup branchGroup,
+ J3dMessage messages[], int startIndex) {
+
+ BranchGroupRetained bgr = (BranchGroupRetained)branchGroup.retained;
+ J3dMessage destroyMessage;
+
+ if (!branchGroup.isLive())
+ return;
+ bgr.attachedToLocale = false;
+ branchGroups.removeElement(branchGroup);
+ universe.setLiveState.reset(this);
+ bgr.clearLive(universe.setLiveState);
+ bgr.setParent(null);
+ bgr.setLocale(null);
+
+ if (messages == null) {
+ destroyMessage = new J3dMessage();
+ } else {
+ destroyMessage = messages[startIndex++];
+ }
+ destroyMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ destroyMessage.type = J3dMessage.ORDERED_GROUP_REMOVED;
+ destroyMessage.universe = universe;
+ destroyMessage.args[0] = universe.setLiveState.ogList.toArray();
+ destroyMessage.args[1] = universe.setLiveState.ogChildIdList.toArray();
+ destroyMessage.args[3] = universe.setLiveState.ogCIOList.toArray();
+ destroyMessage.args[4] = universe.setLiveState.ogCIOTableList.toArray();
+
+ // Issue 312: We need to send the REMOVE_NODES message to the
+ // RenderingEnvironmentStructure before we send VIEWSPECIFICGROUP_CLEAR,
+ // since the latter clears the list of views that is referred to by
+ // scopedNodesViewList and used by removeNodes.
+ if (messages == null) {
+ VirtualUniverse.mc.processMessage(destroyMessage);
+ destroyMessage = new J3dMessage();
+ } else {
+ destroyMessage = messages[startIndex++];
+ }
+ destroyMessage.threads = universe.setLiveState.notifyThreads;
+ destroyMessage.type = J3dMessage.REMOVE_NODES;
+ destroyMessage.universe = universe;
+ destroyMessage.args[0] = universe.setLiveState.nodeList.toArray();
+ if (universe.setLiveState.viewScopedNodeList != null) {
+ destroyMessage.args[3] = universe.setLiveState.viewScopedNodeList;
+ destroyMessage.args[4] = universe.setLiveState.scopedNodesViewList;
+ }
+
+ if (messages == null) {
+ VirtualUniverse.mc.processMessage(destroyMessage);
+ destroyMessage = new J3dMessage();
+ } else {
+ destroyMessage = messages[startIndex++];
+ }
+ destroyMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ destroyMessage.type = J3dMessage.VIEWSPECIFICGROUP_CLEAR;
+ destroyMessage.universe = universe;
+ destroyMessage.args[0] = universe.setLiveState.changedViewGroup;
+ destroyMessage.args[1] = universe.setLiveState.keyList;
+
+ if (messages == null) {
+ VirtualUniverse.mc.processMessage(destroyMessage);
+ } else {
+ destroyMessage = messages[startIndex++];
+ }
+
+ if (universe.isEmpty()) {
+ VirtualUniverse.mc.postRequest(MasterControl.EMPTY_UNIVERSE,
+ universe);
+ }
+ universe.setLiveState.reset(null); // cleanup memory
+ universe.notifyStructureChangeListeners(false, this, branchGroup);
+ }
+
+ /**
+ * Replaces the branch graph rooted at oldGroup in the list of
+ * branch graphs with the branch graph rooted at
+ * newGroup.
+ * @param oldGroup root of the branch graph to be replaced.
+ * @param newGroup root of the branch graph that will replace the old
+ * branch graph.
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ * @exception CapabilityNotSetException if the ALLOW_DETACH capability is
+ * not set in the old BranchGroup node.
+ * @exception MultipleParentException if the new BranchGroup node
+ * is already live.
+ */
+ public void replaceBranchGraph(BranchGroup oldGroup,
+ BranchGroup newGroup){
+
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ if (! oldGroup.getCapability(BranchGroup.ALLOW_DETACH)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("Locale1"));
+ }
+
+ if (((BranchGroupRetained)newGroup.retained).parent != null) {
+ throw new MultipleParentException(J3dI18N.getString("Locale3"));
+ }
+ universe.resetWaitMCFlag();
+ universe.notifyStructureChangeListeners(true, this, newGroup);
+ synchronized (universe.sceneGraphLock) {
+ doReplaceBranchGraph(oldGroup, newGroup);
+ universe.setLiveState.reset(this);
+ }
+ universe.notifyStructureChangeListeners(false, this, oldGroup);
+ universe.waitForMC();
+ }
+
+ // The method that does the work once the lock is acquired.
+ void doReplaceBranchGraph(BranchGroup oldGroup,
+ BranchGroup newGroup){
+ BranchGroupRetained obgr = (BranchGroupRetained)oldGroup.retained;
+ BranchGroupRetained nbgr = (BranchGroupRetained)newGroup.retained;
+ J3dMessage createMessage;
+ J3dMessage destroyMessage;
+
+
+ branchGroups.removeElement(oldGroup);
+ obgr.attachedToLocale = false;
+ universe.setLiveState.reset(this);
+ obgr.clearLive(universe.setLiveState);
+
+ destroyMessage = new J3dMessage();
+
+ destroyMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ destroyMessage.type = J3dMessage.ORDERED_GROUP_REMOVED;
+ destroyMessage.universe = universe;
+ destroyMessage.args[0] = universe.setLiveState.ogList.toArray();
+ destroyMessage.args[1] = universe.setLiveState.ogChildIdList.toArray();
+ destroyMessage.args[3] = universe.setLiveState.ogCIOList.toArray();
+ destroyMessage.args[4] = universe.setLiveState.ogCIOTableList.toArray();
+ VirtualUniverse.mc.processMessage(destroyMessage);
+
+ destroyMessage = new J3dMessage();
+ destroyMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ destroyMessage.type = J3dMessage.VIEWSPECIFICGROUP_CLEAR;
+ destroyMessage.universe = universe;
+ destroyMessage.args[0] = universe.setLiveState.changedViewGroup;
+ destroyMessage.args[1] = universe.setLiveState.keyList;
+ VirtualUniverse.mc.processMessage(destroyMessage);
+
+
+ destroyMessage = new J3dMessage();
+ destroyMessage.threads = universe.setLiveState.notifyThreads;
+ destroyMessage.type = J3dMessage.REMOVE_NODES;
+ destroyMessage.universe = universe;
+ destroyMessage.args[0] = universe.setLiveState.nodeList.toArray();
+ VirtualUniverse.mc.processMessage(destroyMessage);
+
+ branchGroups.addElement(newGroup);
+ nbgr.attachedToLocale = true;
+ universe.setLiveState.reset(this);
+ universe.setLiveState.currentTransforms[0] = new Transform3D[2];
+ universe.setLiveState.currentTransforms[0][0] = new Transform3D();
+ universe.setLiveState.currentTransforms[0][1] = new Transform3D();
+ universe.setLiveState.currentTransformsIndex[0] = new int[2];
+ universe.setLiveState.currentTransformsIndex[0][0] = 0;
+ universe.setLiveState.currentTransformsIndex[0][1] = 0;
+
+ universe.setLiveState.localToVworld =
+ universe.setLiveState.currentTransforms;
+ universe.setLiveState.localToVworldIndex =
+ universe.setLiveState.currentTransformsIndex;
+
+ universe.setLiveState.branchGroupPaths = new ArrayList<BranchGroupRetained[]>();
+ universe.setLiveState.branchGroupPaths.add(new BranchGroupRetained[0]);
+
+ universe.setLiveState.orderedPaths = new ArrayList<OrderedPath>(1);
+ universe.setLiveState.orderedPaths.add(new OrderedPath());
+
+ universe.setLiveState.switchStates = new ArrayList<SwitchState>(1);
+ universe.setLiveState.switchStates.add(new SwitchState(false));
+
+ nbgr.setLive(universe.setLiveState);
+
+
+ createMessage = new J3dMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
+ createMessage.type = J3dMessage.ORDERED_GROUP_INSERTED;
+ createMessage.universe = universe;
+ createMessage.args[0] = universe.setLiveState.ogList.toArray();
+ createMessage.args[1] = universe.setLiveState.ogChildIdList.toArray();
+ createMessage.args[2] = universe.setLiveState.ogOrderedIdList.toArray();
+ createMessage.args[3] = universe.setLiveState.ogCIOList.toArray();
+ createMessage.args[4] = universe.setLiveState.ogCIOTableList.toArray();
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ // XXXX: make these two into one message
+ createMessage = new J3dMessage();
+ createMessage.threads = universe.setLiveState.notifyThreads;
+ createMessage.type = J3dMessage.INSERT_NODES;
+ createMessage.universe = universe;
+ createMessage.args[0] = universe.setLiveState.nodeList.toArray();
+ createMessage.args[1] = null;
+ createMessage.args[2] = null;
+ if (universe.setLiveState.viewScopedNodeList != null) {
+ createMessage.args[3] = universe.setLiveState.viewScopedNodeList;
+ createMessage.args[4] = universe.setLiveState.scopedNodesViewList;
+ }
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ BehaviorRetained[] behavNodes = new BehaviorRetained[universe.setLiveState.behaviorNodes.size()];
+ behavNodes = universe.setLiveState.behaviorNodes.toArray(behavNodes);
+
+ if (universe.isEmpty()) {
+ VirtualUniverse.mc.postRequest(MasterControl.EMPTY_UNIVERSE,
+ universe);
+ }
+
+ for (int i=0; i< behavNodes.length; i++) {
+ behavNodes[i].executeInitialize();
+ }
+
+ createMessage = new J3dMessage();
+ createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
+ createMessage.type = J3dMessage.BEHAVIOR_ACTIVATE;
+ createMessage.universe = universe;
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ // Free up memory.
+ universe.setLiveState.reset(null);
+ }
+
+ /**
+ * Get number of branch graphs in this Locale.
+ * @return number of branch graphs in this Locale.
+ */
+ public int numBranchGraphs(){
+ return branchGroups.size();
+ }
+
+ /**
+ * Gets an Enumeration object of all branch graphs in this Locale.
+ * @return an Enumeration object of all branch graphs.
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ */
+ public Enumeration getAllBranchGraphs(){
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ return branchGroups.elements();
+ }
+
+
+ void validateModeFlagAndPickShape(int mode, int flags, PickShape pickShape) {
+
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ if((mode != PickInfo.PICK_BOUNDS) && (mode != PickInfo.PICK_GEOMETRY)) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("Locale5"));
+ }
+
+ if((pickShape instanceof PickPoint) && (mode == PickInfo.PICK_GEOMETRY)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Locale6"));
+ }
+
+ if(((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) &&
+ ((flags & PickInfo.ALL_GEOM_INFO) != 0)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Locale7"));
+ }
+
+ if((mode == PickInfo.PICK_BOUNDS) &&
+ (((flags & (PickInfo.CLOSEST_GEOM_INFO |
+ PickInfo.ALL_GEOM_INFO |
+ PickInfo.CLOSEST_DISTANCE |
+ PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("Locale8"));
+ }
+
+ if((pickShape instanceof PickBounds) &&
+ (((flags & (PickInfo.CLOSEST_GEOM_INFO |
+ PickInfo.ALL_GEOM_INFO |
+ PickInfo.CLOSEST_DISTANCE |
+ PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("Locale9"));
+ }
+ }
+
+ /**
+ * Returns an array referencing all the items that are pickable below this
+ * <code>Locale</code> that intersect with PickShape.
+ * The resultant array is unordered.
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @see BranchGroup#pickAll
+ */
+ public SceneGraphPath[] pickAll( PickShape pickShape ) {
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ PickInfo[] pickInfoArr = pickAll( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+ SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
+ for( int i=0; i<sgpArr.length; i++) {
+ sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
+ }
+
+ return sgpArr;
+
+ }
+
+
+ /**
+ * Returns an array unsorted references to all the PickInfo objects that are pickable
+ * below this <code>Locale</code> that intersect with PickShape.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickAll(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo[] pickAll( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+
+ GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(this, pickShape);
+
+ return PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+
+ }
+
+ /**
+ * Returns a sorted array of references to all the pickable items
+ * that intersect with the pickShape. Element [0] references the
+ * item closest to <i>origin</i> of PickShape successive array
+ * elements are further from the <i>origin</i>
+ * <br>
+ * NOTE: If pickShape is of type PickBounds, the resulting array
+ * is unordered.
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @see BranchGroup#pickAllSorted
+ */
+ public SceneGraphPath[] pickAllSorted( PickShape pickShape ) {
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ PickInfo[] pickInfoArr = pickAllSorted( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+ SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
+ for( int i=0; i<sgpArr.length; i++) {
+ sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
+ }
+
+ return sgpArr;
+
+ }
+
+ /**
+ * Returns a sorted array of PickInfo references to all the pickable
+ * items that intersect with the pickShape. Element [0] references
+ * the item closest to <i>origin</i> of PickShape successive array
+ * elements are further from the <i>origin</i>
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickAllSorted(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo[] pickAllSorted( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(this, pickShape);
+
+ if ((geomAtoms == null) || (geomAtoms.length == 0)) {
+ return null;
+ }
+
+ PickInfo[] pickInfoArr = null;
+
+ if (mode == PickInfo.PICK_GEOMETRY) {
+ // Need to have closestDistance set
+ flags |= PickInfo.CLOSEST_DISTANCE;
+ pickInfoArr= PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+ if (pickInfoArr != null) {
+ PickInfo.sortPickInfoArray(pickInfoArr);
+ }
+ }
+ else {
+ PickInfo.sortGeomAtoms(geomAtoms, pickShape);
+ pickInfoArr= PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+ }
+
+ return pickInfoArr;
+ }
+
+ /**
+ * Returns a SceneGraphPath which references the pickable item
+ * which is closest to the origin of <code>pickShape</code>.
+ * <br>
+ * NOTE: If pickShape is of type PickBounds, the return is any
+ * pickable node below this Locale.
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @see BranchGroup#pickClosest
+ */
+ public SceneGraphPath pickClosest( PickShape pickShape ) {
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ PickInfo pickInfo = pickClosest( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfo == null) {
+ return null;
+ }
+ return pickInfo.getSceneGraphPath();
+ }
+
+ /**
+ * Returns a PickInfo which references the pickable item
+ * which is closest to the origin of <code>pickShape</code>.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickClosest(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo pickClosest( int mode, int flags, PickShape pickShape ) {
+
+ PickInfo[] pickInfoArr = null;
+
+ pickInfoArr = pickAllSorted( mode, flags, pickShape );
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ return pickInfoArr[0];
+
+ }
+
+ /**
+ * Returns a reference to any item that is Pickable below this
+ * Locale which intersects with <code>pickShape</code>.
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @see BranchGroup#pickAny
+ */
+ public SceneGraphPath pickAny( PickShape pickShape ) {
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ PickInfo pickInfo = pickAny( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfo == null) {
+ return null;
+ }
+ return pickInfo.getSceneGraphPath();
+
+ }
+
+ /**
+ * Returns a PickInfo which references the pickable item below this
+ * Locale which intersects with <code>pickShape</code>.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickAny(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo pickAny( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(this, pickShape);
+
+ PickInfo[] pickInfoArr = PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ANY);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ return pickInfoArr[0];
+
+ }
+
+}