0001: /*
0002: * $RCSfile: Locale.java,v $
0003: *
0004: * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006: *
0007: * This code is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU General Public License version 2 only, as
0009: * published by the Free Software Foundation. Sun designates this
0010: * particular file as subject to the "Classpath" exception as provided
0011: * by Sun in the LICENSE file that accompanied this code.
0012: *
0013: * This code is distributed in the hope that it will be useful, but WITHOUT
0014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: * version 2 for more details (a copy is included in the LICENSE file that
0017: * accompanied this code).
0018: *
0019: * You should have received a copy of the GNU General Public License version
0020: * 2 along with this work; if not, write to the Free Software Foundation,
0021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022: *
0023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024: * CA 95054 USA or visit www.sun.com if you need additional information or
0025: * have any questions.
0026: *
0027: * $Revision: 1.9 $
0028: * $Date: 2008/02/28 20:17:26 $
0029: * $State: Exp $
0030: */
0031:
0032: package javax.media.j3d;
0033:
0034: import javax.vecmath.*;
0035: import java.util.Vector;
0036: import java.util.Enumeration;
0037: import java.util.ArrayList;
0038:
0039: /**
0040: * A Locale object defines a high-resolution position within a
0041: * VirtualUniverse, and serves as a container for a collection of
0042: * BranchGroup-rooted subgraphs (branch graphs), at that position.
0043: * Objects within a Locale are defined using standard double-precision
0044: * coordinates, relative to the origin of the Locale. This origin
0045: * defines the Virtual World coordinate system for that Locale.
0046: * <p>
0047: * A Locale object defines methods to set and get its high-resolution
0048: * coordinates, and methods to add, remove, and enumerate the branch
0049: * graphs.
0050: *
0051: * <p>
0052: * For more information, see the
0053: * <a href="doc-files/intro.html">Introduction to the Java 3D API</a> and
0054: * <a href="doc-files/VirtualUniverse.html">Scene Graph Superstructure</a>
0055: * documents.
0056: *
0057: * @see VirtualUniverse
0058: * @see HiResCoord
0059: * @see BranchGroup
0060: */
0061:
0062: public class Locale extends Object {
0063:
0064: /**
0065: * The virtual universe that this Locale object is contained within.
0066: */
0067: VirtualUniverse universe;
0068:
0069: /**
0070: * The high resolution coordinate associated with this Locale object.
0071: */
0072: HiResCoord hiRes;
0073:
0074: /**
0075: * List of BranchGroup objects included in this Locale
0076: */
0077: Vector branchGroups = new Vector();
0078:
0079: // locale's identifier
0080: String nodeId = null;
0081:
0082: /**
0083: * Constructs and initializes a new high resolution Locale object
0084: * located at (0, 0, 0).
0085: * @param universe the virtual universe that will contain this
0086: * Locale object
0087: */
0088: public Locale(VirtualUniverse universe) {
0089: this .universe = universe;
0090: this .universe.addLocale(this );
0091: this .hiRes = new HiResCoord();
0092: nodeId = universe.getNodeId();
0093: }
0094:
0095: /**
0096: * Constructs and initializes a new high resolution Locale object
0097: * from the parameters provided.
0098: * @param universe the virtual universe that will contain this
0099: * Locale object
0100: * @param x an eight element array specifying the x position
0101: * @param y an eight element array specifying the y position
0102: * @param z an eight element array specifying the z position
0103: */
0104: public Locale(VirtualUniverse universe, int[] x, int[] y, int[] z) {
0105: this .universe = universe;
0106: this .universe.addLocale(this );
0107: this .hiRes = new HiResCoord(x, y, z);
0108: nodeId = universe.getNodeId();
0109: }
0110:
0111: /**
0112: * Constructs and initializes a new high resolution Locale object
0113: * at the location specified by the HiResCoord argument.
0114: * @param universe the virtual universe that will contain this
0115: * Locale object
0116: * @param hiRes the HiRes coordinate to use in creating this Locale
0117: */
0118: public Locale(VirtualUniverse universe, HiResCoord hiRes) {
0119: this .universe = universe;
0120: this .universe.addLocale(this );
0121: this .hiRes = new HiResCoord(hiRes);
0122: nodeId = universe.getNodeId();
0123: }
0124:
0125: /**
0126: * Retrieves the virtual universe within which this Locale object
0127: * is contained. A null reference indicates that this
0128: * Locale has been removed from its VirtualUniverse.
0129: * @return the virtual universe within which this Locale object
0130: * is contained.
0131: */
0132: public VirtualUniverse getVirtualUniverse() {
0133: return universe;
0134: }
0135:
0136: /**
0137: * Sets the HiRes coordinate of this Locale to the location
0138: * specified by the parameters provided.
0139: * @param x an eight element array specifying the x position
0140: * @param y an eight element array specifying the y position
0141: * @param z an eight element array specifying the z position
0142: */
0143: public void setHiRes(int[] x, int[] y, int[] z) {
0144: this .hiRes.setHiResCoord(x, y, z);
0145: }
0146:
0147: /**
0148: * Sets the HiRes coordinate of this Locale
0149: * to the location specified by the HiRes argument.
0150: * @param hiRes the HiRes coordinate specifying this node's new location
0151: */
0152: public void setHiRes(HiResCoord hiRes) {
0153: this .hiRes.setHiResCoord(hiRes);
0154: }
0155:
0156: /**
0157: * Returns this node's HiResCoord.
0158: * @param hiRes a HiResCoord object that will receive the
0159: * HiRes coordinate of this Locale node
0160: */
0161: public void getHiRes(HiResCoord hiRes) {
0162: this .hiRes.getHiResCoord(hiRes);
0163: }
0164:
0165: /**
0166: * Add a new branch graph rooted at BranchGroup to
0167: * the list of branch graphs.
0168: * @param branchGroup root of the branch graph to be added
0169: * @exception IllegalStateException if this Locale has been
0170: * removed from its VirtualUniverse.
0171: * @exception MultipleParentException if the specified BranchGroup node
0172: * is already live.
0173: */
0174: public void addBranchGraph(BranchGroup branchGroup) {
0175: if (universe == null) {
0176: throw new IllegalStateException(J3dI18N
0177: .getString("Locale4"));
0178: }
0179:
0180: // if the BranchGroup already has a parent, or has already been
0181: // added to a locale, throw MultipleParentException
0182: if ((((BranchGroupRetained) branchGroup.retained).parent != null)
0183: || (branchGroup.isLive())) {
0184: throw new MultipleParentException(J3dI18N
0185: .getString("Locale0"));
0186: }
0187:
0188: universe
0189: .notifyStructureChangeListeners(true, this , branchGroup);
0190: universe.resetWaitMCFlag();
0191: synchronized (universe.sceneGraphLock) {
0192: doAddBranchGraph(branchGroup);
0193: universe.setLiveState.reset(this );
0194: }
0195: universe.waitForMC();
0196: }
0197:
0198: // The method that does the work once the lock is acquired.
0199: void doAddBranchGraph(BranchGroup branchGroup) {
0200: BranchGroupRetained bgr = (BranchGroupRetained) branchGroup.retained;
0201: J3dMessage createMessage;
0202: SetLiveState s = universe.setLiveState;
0203:
0204: // bgr.setLocale(this);
0205:
0206: // addElement needs to precede setLive or else any liveness checks
0207: // in the initialize() call of a user behavior (ie, calling collision
0208: // or picking constructor with a SceneGraphPath) will fail
0209: // when SceneGraphPath.validate() attempts to verify that
0210: // the proper Locale is associated with that SceneGraphPath
0211: bgr.attachedToLocale = true;
0212: branchGroups.addElement(branchGroup);
0213: s.reset(this );
0214: s.currentTransforms[0] = new Transform3D[2];
0215: s.currentTransforms[0][0] = new Transform3D();
0216: s.currentTransforms[0][1] = new Transform3D();
0217: s.currentTransformsIndex[0] = new int[2];
0218: s.currentTransformsIndex[0][0] = 0;
0219: s.currentTransformsIndex[0][1] = 0;
0220:
0221: s.localToVworld = s.currentTransforms;
0222: s.localToVworldIndex = s.currentTransformsIndex;
0223:
0224: s.branchGroupPaths = new ArrayList();
0225: s.branchGroupPaths.add(new BranchGroupRetained[0]);
0226:
0227: s.orderedPaths = new ArrayList(1);
0228: s.orderedPaths.add(new OrderedPath());
0229:
0230: s.switchStates = new ArrayList(1);
0231: s.switchStates.add(new SwitchState(false));
0232:
0233: bgr.setLive(s);
0234:
0235: createMessage = new J3dMessage();
0236: createMessage.threads = J3dThread.UPDATE_RENDER
0237: | J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0238: createMessage.type = J3dMessage.ORDERED_GROUP_INSERTED;
0239: createMessage.universe = universe;
0240: createMessage.args[0] = s.ogList.toArray();
0241: createMessage.args[1] = s.ogChildIdList.toArray();
0242: createMessage.args[2] = s.ogOrderedIdList.toArray();
0243: createMessage.args[3] = s.ogCIOList.toArray();
0244: createMessage.args[4] = s.ogCIOTableList.toArray();
0245:
0246: VirtualUniverse.mc.processMessage(createMessage);
0247:
0248: createMessage = new J3dMessage();
0249: createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0250: createMessage.type = J3dMessage.VIEWSPECIFICGROUP_INIT;
0251: createMessage.universe = universe;
0252: createMessage.args[0] = s.changedViewGroup;
0253: createMessage.args[1] = s.changedViewList;
0254: createMessage.args[2] = s.keyList;
0255: VirtualUniverse.mc.processMessage(createMessage);
0256:
0257: createMessage = new J3dMessage();
0258: createMessage.threads = s.notifyThreads;
0259: createMessage.type = J3dMessage.INSERT_NODES;
0260: createMessage.universe = universe;
0261: createMessage.args[0] = s.nodeList.toArray();
0262: createMessage.args[1] = null;
0263: createMessage.args[2] = null;
0264: if (s.viewScopedNodeList != null) {
0265: createMessage.args[3] = s.viewScopedNodeList;
0266: createMessage.args[4] = s.scopedNodesViewList;
0267: }
0268: VirtualUniverse.mc.processMessage(createMessage);
0269:
0270: int sz = s.behaviorNodes.size();
0271: for (int i = 0; i < sz; i++) {
0272: BehaviorRetained b;
0273: b = (BehaviorRetained) s.behaviorNodes.get(i);
0274: b.executeInitialize();
0275: }
0276:
0277: createMessage = new J3dMessage();
0278: createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
0279: createMessage.type = J3dMessage.BEHAVIOR_ACTIVATE;
0280: createMessage.universe = universe;
0281: VirtualUniverse.mc.processMessage(createMessage);
0282:
0283: // Free up memory.
0284: s.reset(null);
0285: }
0286:
0287: /**
0288: * Removes a branch graph rooted at BranchGroup from
0289: * the list of branch graphs.
0290: * @param branchGroup root of the branch graph to be removed
0291: * @exception IllegalStateException if this Locale has been
0292: * removed from its VirtualUniverse.
0293: * @exception CapabilityNotSetException if the ALLOW_DETACH capability is
0294: * not set in the specified BranchGroup node.
0295: */
0296: public void removeBranchGraph(BranchGroup branchGroup) {
0297: if (universe == null) {
0298: throw new IllegalStateException(J3dI18N
0299: .getString("Locale4"));
0300: }
0301:
0302: if (!branchGroup.getCapability(BranchGroup.ALLOW_DETACH)) {
0303: throw new CapabilityNotSetException(J3dI18N
0304: .getString("Locale1"));
0305: }
0306: universe.resetWaitMCFlag();
0307: synchronized (universe.sceneGraphLock) {
0308: doRemoveBranchGraph(branchGroup, null, 0);
0309: universe.setLiveState.reset(this );
0310: }
0311: universe.waitForMC();
0312: }
0313:
0314: // Method to remove all branch graphs from this Locale and remove
0315: // this Locale from the VirtualUniverse
0316: void removeFromUniverse() {
0317: if (branchGroups.size() > 0) {
0318: universe.resetWaitMCFlag();
0319: synchronized (universe.sceneGraphLock) {
0320: // Make a copy of the branchGroups list so that we can safely
0321: // iterate over it.
0322: Object[] bg = branchGroups.toArray();
0323: for (int i = 0; i < bg.length; i++) {
0324: doRemoveBranchGraph((BranchGroup) bg[i], null, 0);
0325: }
0326: }
0327: // Put after sceneGraphLock to prevent deadlock
0328: universe.waitForMC();
0329: }
0330:
0331: // free nodeId
0332: if (nodeId != null) {
0333: universe.nodeIdFreeList.addElement(nodeId);
0334: nodeId = null;
0335: }
0336:
0337: // Set universe pointer to null, indicating that this Locale
0338: // has been removed from its universe
0339: universe = null;
0340: }
0341:
0342: // The method that does the work once the lock is acquired.
0343: void doRemoveBranchGraph(BranchGroup branchGroup,
0344: J3dMessage messages[], int startIndex) {
0345:
0346: BranchGroupRetained bgr = (BranchGroupRetained) branchGroup.retained;
0347: J3dMessage destroyMessage;
0348:
0349: if (!branchGroup.isLive())
0350: return;
0351: bgr.attachedToLocale = false;
0352: branchGroups.removeElement(branchGroup);
0353: universe.setLiveState.reset(this );
0354: bgr.clearLive(universe.setLiveState);
0355: bgr.setParent(null);
0356: bgr.setLocale(null);
0357:
0358: if (messages == null) {
0359: destroyMessage = new J3dMessage();
0360: } else {
0361: destroyMessage = messages[startIndex++];
0362: }
0363: destroyMessage.threads = J3dThread.UPDATE_RENDER
0364: | J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0365: destroyMessage.type = J3dMessage.ORDERED_GROUP_REMOVED;
0366: destroyMessage.universe = universe;
0367: destroyMessage.args[0] = universe.setLiveState.ogList.toArray();
0368: destroyMessage.args[1] = universe.setLiveState.ogChildIdList
0369: .toArray();
0370: destroyMessage.args[3] = universe.setLiveState.ogCIOList
0371: .toArray();
0372: destroyMessage.args[4] = universe.setLiveState.ogCIOTableList
0373: .toArray();
0374:
0375: // Issue 312: We need to send the REMOVE_NODES message to the
0376: // RenderingEnvironmentStructure before we send VIEWSPECIFICGROUP_CLEAR,
0377: // since the latter clears the list of views that is referred to by
0378: // scopedNodesViewList and used by removeNodes.
0379: if (messages == null) {
0380: VirtualUniverse.mc.processMessage(destroyMessage);
0381: destroyMessage = new J3dMessage();
0382: } else {
0383: destroyMessage = messages[startIndex++];
0384: }
0385: destroyMessage.threads = universe.setLiveState.notifyThreads;
0386: destroyMessage.type = J3dMessage.REMOVE_NODES;
0387: destroyMessage.universe = universe;
0388: destroyMessage.args[0] = universe.setLiveState.nodeList
0389: .toArray();
0390: if (universe.setLiveState.viewScopedNodeList != null) {
0391: destroyMessage.args[3] = universe.setLiveState.viewScopedNodeList;
0392: destroyMessage.args[4] = universe.setLiveState.scopedNodesViewList;
0393: }
0394:
0395: if (messages == null) {
0396: VirtualUniverse.mc.processMessage(destroyMessage);
0397: destroyMessage = new J3dMessage();
0398: } else {
0399: destroyMessage = messages[startIndex++];
0400: }
0401: destroyMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0402: destroyMessage.type = J3dMessage.VIEWSPECIFICGROUP_CLEAR;
0403: destroyMessage.universe = universe;
0404: destroyMessage.args[0] = universe.setLiveState.changedViewGroup;
0405: destroyMessage.args[1] = universe.setLiveState.keyList;
0406:
0407: if (messages == null) {
0408: VirtualUniverse.mc.processMessage(destroyMessage);
0409: } else {
0410: destroyMessage = messages[startIndex++];
0411: }
0412:
0413: if (universe.isEmpty()) {
0414: VirtualUniverse.mc.postRequest(
0415: MasterControl.EMPTY_UNIVERSE, universe);
0416: }
0417: universe.setLiveState.reset(null); // cleanup memory
0418: universe.notifyStructureChangeListeners(false, this ,
0419: branchGroup);
0420: }
0421:
0422: /**
0423: * Replaces the branch graph rooted at oldGroup in the list of
0424: * branch graphs with the branch graph rooted at
0425: * newGroup.
0426: * @param oldGroup root of the branch graph to be replaced.
0427: * @param newGroup root of the branch graph that will replace the old
0428: * branch graph.
0429: * @exception IllegalStateException if this Locale has been
0430: * removed from its VirtualUniverse.
0431: * @exception CapabilityNotSetException if the ALLOW_DETACH capability is
0432: * not set in the old BranchGroup node.
0433: * @exception MultipleParentException if the new BranchGroup node
0434: * is already live.
0435: */
0436: public void replaceBranchGraph(BranchGroup oldGroup,
0437: BranchGroup newGroup) {
0438:
0439: if (universe == null) {
0440: throw new IllegalStateException(J3dI18N
0441: .getString("Locale4"));
0442: }
0443:
0444: if (!oldGroup.getCapability(BranchGroup.ALLOW_DETACH)) {
0445: throw new CapabilityNotSetException(J3dI18N
0446: .getString("Locale1"));
0447: }
0448:
0449: if (((BranchGroupRetained) newGroup.retained).parent != null) {
0450: throw new MultipleParentException(J3dI18N
0451: .getString("Locale3"));
0452: }
0453: universe.resetWaitMCFlag();
0454: universe.notifyStructureChangeListeners(true, this , newGroup);
0455: synchronized (universe.sceneGraphLock) {
0456: doReplaceBranchGraph(oldGroup, newGroup);
0457: universe.setLiveState.reset(this );
0458: }
0459: universe.notifyStructureChangeListeners(false, this , oldGroup);
0460: universe.waitForMC();
0461: }
0462:
0463: // The method that does the work once the lock is acquired.
0464: void doReplaceBranchGraph(BranchGroup oldGroup, BranchGroup newGroup) {
0465: BranchGroupRetained obgr = (BranchGroupRetained) oldGroup.retained;
0466: BranchGroupRetained nbgr = (BranchGroupRetained) newGroup.retained;
0467: J3dMessage createMessage;
0468: J3dMessage destroyMessage;
0469:
0470: branchGroups.removeElement(oldGroup);
0471: obgr.attachedToLocale = false;
0472: universe.setLiveState.reset(this );
0473: obgr.clearLive(universe.setLiveState);
0474:
0475: destroyMessage = new J3dMessage();
0476:
0477: destroyMessage.threads = J3dThread.UPDATE_RENDER
0478: | J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0479: destroyMessage.type = J3dMessage.ORDERED_GROUP_REMOVED;
0480: destroyMessage.universe = universe;
0481: destroyMessage.args[0] = universe.setLiveState.ogList.toArray();
0482: destroyMessage.args[1] = universe.setLiveState.ogChildIdList
0483: .toArray();
0484: destroyMessage.args[3] = universe.setLiveState.ogCIOList
0485: .toArray();
0486: destroyMessage.args[4] = universe.setLiveState.ogCIOTableList
0487: .toArray();
0488: VirtualUniverse.mc.processMessage(destroyMessage);
0489:
0490: destroyMessage = new J3dMessage();
0491: destroyMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0492: destroyMessage.type = J3dMessage.VIEWSPECIFICGROUP_CLEAR;
0493: destroyMessage.universe = universe;
0494: destroyMessage.args[0] = universe.setLiveState.changedViewGroup;
0495: destroyMessage.args[1] = universe.setLiveState.keyList;
0496: VirtualUniverse.mc.processMessage(destroyMessage);
0497:
0498: destroyMessage = new J3dMessage();
0499: destroyMessage.threads = universe.setLiveState.notifyThreads;
0500: destroyMessage.type = J3dMessage.REMOVE_NODES;
0501: destroyMessage.universe = universe;
0502: destroyMessage.args[0] = universe.setLiveState.nodeList
0503: .toArray();
0504: VirtualUniverse.mc.processMessage(destroyMessage);
0505:
0506: branchGroups.addElement(newGroup);
0507: nbgr.attachedToLocale = true;
0508: universe.setLiveState.reset(this );
0509: universe.setLiveState.currentTransforms[0] = new Transform3D[2];
0510: universe.setLiveState.currentTransforms[0][0] = new Transform3D();
0511: universe.setLiveState.currentTransforms[0][1] = new Transform3D();
0512: universe.setLiveState.currentTransformsIndex[0] = new int[2];
0513: universe.setLiveState.currentTransformsIndex[0][0] = 0;
0514: universe.setLiveState.currentTransformsIndex[0][1] = 0;
0515:
0516: universe.setLiveState.localToVworld = universe.setLiveState.currentTransforms;
0517: universe.setLiveState.localToVworldIndex = universe.setLiveState.currentTransformsIndex;
0518:
0519: universe.setLiveState.branchGroupPaths = new ArrayList();
0520: universe.setLiveState.branchGroupPaths
0521: .add(new BranchGroupRetained[0]);
0522:
0523: universe.setLiveState.orderedPaths = new ArrayList(1);
0524: universe.setLiveState.orderedPaths.add(new OrderedPath());
0525:
0526: universe.setLiveState.switchStates = new ArrayList(1);
0527: universe.setLiveState.switchStates.add(new SwitchState(false));
0528:
0529: nbgr.setLive(universe.setLiveState);
0530:
0531: createMessage = new J3dMessage();
0532: createMessage.threads = J3dThread.UPDATE_RENDER
0533: | J3dThread.UPDATE_RENDERING_ENVIRONMENT;
0534: createMessage.type = J3dMessage.ORDERED_GROUP_INSERTED;
0535: createMessage.universe = universe;
0536: createMessage.args[0] = universe.setLiveState.ogList.toArray();
0537: createMessage.args[1] = universe.setLiveState.ogChildIdList
0538: .toArray();
0539: createMessage.args[2] = universe.setLiveState.ogOrderedIdList
0540: .toArray();
0541: createMessage.args[3] = universe.setLiveState.ogCIOList
0542: .toArray();
0543: createMessage.args[4] = universe.setLiveState.ogCIOTableList
0544: .toArray();
0545: VirtualUniverse.mc.processMessage(createMessage);
0546:
0547: // XXXX: make these two into one message
0548: createMessage = new J3dMessage();
0549: createMessage.threads = universe.setLiveState.notifyThreads;
0550: createMessage.type = J3dMessage.INSERT_NODES;
0551: createMessage.universe = universe;
0552: createMessage.args[0] = universe.setLiveState.nodeList
0553: .toArray();
0554: createMessage.args[1] = null;
0555: createMessage.args[2] = null;
0556: if (universe.setLiveState.viewScopedNodeList != null) {
0557: createMessage.args[3] = universe.setLiveState.viewScopedNodeList;
0558: createMessage.args[4] = universe.setLiveState.scopedNodesViewList;
0559: }
0560: VirtualUniverse.mc.processMessage(createMessage);
0561:
0562: Object behaviorNodes[] = universe.setLiveState.behaviorNodes
0563: .toArray();
0564:
0565: if (universe.isEmpty()) {
0566: VirtualUniverse.mc.postRequest(
0567: MasterControl.EMPTY_UNIVERSE, universe);
0568: }
0569:
0570: for (int i = 0; i < behaviorNodes.length; i++) {
0571: ((BehaviorRetained) behaviorNodes[i]).executeInitialize();
0572: }
0573:
0574: createMessage = new J3dMessage();
0575: createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
0576: createMessage.type = J3dMessage.BEHAVIOR_ACTIVATE;
0577: createMessage.universe = universe;
0578: VirtualUniverse.mc.processMessage(createMessage);
0579:
0580: // Free up memory.
0581: universe.setLiveState.reset(null);
0582: }
0583:
0584: /**
0585: * Get number of branch graphs in this Locale.
0586: * @return number of branch graphs in this Locale.
0587: */
0588: public int numBranchGraphs() {
0589: return branchGroups.size();
0590: }
0591:
0592: /**
0593: * Gets an Enumeration object of all branch graphs in this Locale.
0594: * @return an Enumeration object of all branch graphs.
0595: * @exception IllegalStateException if this Locale has been
0596: * removed from its VirtualUniverse.
0597: */
0598: public Enumeration getAllBranchGraphs() {
0599: if (universe == null) {
0600: throw new IllegalStateException(J3dI18N
0601: .getString("Locale4"));
0602: }
0603:
0604: return branchGroups.elements();
0605: }
0606:
0607: void validateModeFlagAndPickShape(int mode, int flags,
0608: PickShape pickShape) {
0609:
0610: if (universe == null) {
0611: throw new IllegalStateException(J3dI18N
0612: .getString("Locale4"));
0613: }
0614:
0615: if ((mode != PickInfo.PICK_BOUNDS)
0616: && (mode != PickInfo.PICK_GEOMETRY)) {
0617:
0618: throw new IllegalArgumentException(J3dI18N
0619: .getString("Locale5"));
0620: }
0621:
0622: if ((pickShape instanceof PickPoint)
0623: && (mode == PickInfo.PICK_GEOMETRY)) {
0624: throw new IllegalArgumentException(J3dI18N
0625: .getString("Locale6"));
0626: }
0627:
0628: if (((flags & PickInfo.CLOSEST_GEOM_INFO) != 0)
0629: && ((flags & PickInfo.ALL_GEOM_INFO) != 0)) {
0630: throw new IllegalArgumentException(J3dI18N
0631: .getString("Locale7"));
0632: }
0633:
0634: if ((mode == PickInfo.PICK_BOUNDS)
0635: && (((flags & (PickInfo.CLOSEST_GEOM_INFO
0636: | PickInfo.ALL_GEOM_INFO
0637: | PickInfo.CLOSEST_DISTANCE | PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
0638:
0639: throw new IllegalArgumentException(J3dI18N
0640: .getString("Locale8"));
0641: }
0642:
0643: if ((pickShape instanceof PickBounds)
0644: && (((flags & (PickInfo.CLOSEST_GEOM_INFO
0645: | PickInfo.ALL_GEOM_INFO
0646: | PickInfo.CLOSEST_DISTANCE | PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
0647:
0648: throw new IllegalArgumentException(J3dI18N
0649: .getString("Locale9"));
0650: }
0651: }
0652:
0653: /**
0654: * Returns an array referencing all the items that are pickable below this
0655: * <code>Locale</code> that intersect with PickShape.
0656: * The resultant array is unordered.
0657: *
0658: * @param pickShape the description of this picking volume or area.
0659: *
0660: * @exception IllegalStateException if this Locale has been
0661: * removed from its VirtualUniverse.
0662: *
0663: * @see BranchGroup#pickAll
0664: */
0665: public SceneGraphPath[] pickAll(PickShape pickShape) {
0666: if (universe == null) {
0667: throw new IllegalStateException(J3dI18N
0668: .getString("Locale4"));
0669: }
0670:
0671: PickInfo[] pickInfoArr = pickAll(PickInfo.PICK_BOUNDS,
0672: PickInfo.SCENEGRAPHPATH, pickShape);
0673:
0674: if (pickInfoArr == null) {
0675: return null;
0676: }
0677: SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
0678: for (int i = 0; i < sgpArr.length; i++) {
0679: sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
0680: }
0681:
0682: return sgpArr;
0683:
0684: }
0685:
0686: /**
0687: * Returns an array unsorted references to all the PickInfo objects that are pickable
0688: * below this <code>Locale</code> that intersect with PickShape.
0689: * The accuracy of the pick is set by the pick mode. The mode include :
0690: * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
0691: * is specified via a masked variable, flags, indicating which components are
0692: * present in each returned PickInfo object.
0693: *
0694: * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
0695: *
0696: * @param flags a mask indicating which components are present in each PickInfo object.
0697: * This is specified as one or more individual bits that are bitwise "OR"ed together to
0698: * describe the PickInfo data. The flags include :
0699: * <ul>
0700: * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
0701: * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
0702: * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
0703: * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
0704: * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
0705: * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
0706: * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
0707: * </ul>
0708: *
0709: * @param pickShape the description of this picking volume or area.
0710: *
0711: * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
0712: * ALL_GEOM_INFO.
0713: *
0714: * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
0715: * is set to PICK_GEOMETRY.
0716: *
0717: * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
0718: * nor PICK_GEOMETRY.
0719: *
0720: * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
0721: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
0722: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
0723: *
0724: * @exception IllegalArgumentException if pickShape is PickBounds
0725: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
0726: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
0727: *
0728: * @exception IllegalStateException if this Locale has been
0729: * removed from its VirtualUniverse.
0730: *
0731: * @exception CapabilityNotSetException if the mode is
0732: * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
0733: * is not set in any Geometry objects referred to by any shape
0734: * node whose bounds intersects the PickShape.
0735: *
0736: * @exception CapabilityNotSetException if flags contains any of
0737: * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
0738: * or ALL_GEOM_INFO, and the capability bits that control reading of
0739: * coordinate data are not set in any GeometryArray object referred
0740: * to by any shape node that intersects the PickShape.
0741: * The capability bits that must be set to avoid this exception are as follows :
0742: * <ul>
0743: * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
0744: * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
0745: * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
0746: * (in addition to one of the above)</li>
0747: * </ul>
0748: *
0749: * @see BranchGroup#pickAll(int,int,javax.media.j3d.PickShape)
0750: * @see PickInfo
0751: *
0752: * @since Java 3D 1.4
0753: *
0754: */
0755: public PickInfo[] pickAll(int mode, int flags, PickShape pickShape) {
0756:
0757: validateModeFlagAndPickShape(mode, flags, pickShape);
0758:
0759: GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(
0760: this , pickShape);
0761:
0762: return PickInfo.pick(this , geomAtoms, mode, flags, pickShape,
0763: PickInfo.PICK_ALL);
0764:
0765: }
0766:
0767: /**
0768: * Returns a sorted array of references to all the pickable items
0769: * that intersect with the pickShape. Element [0] references the
0770: * item closest to <i>origin</i> of PickShape successive array
0771: * elements are further from the <i>origin</i>
0772: * <br>
0773: * NOTE: If pickShape is of type PickBounds, the resulting array
0774: * is unordered.
0775: *
0776: * @param pickShape the description of this picking volume or area.
0777: *
0778: * @exception IllegalStateException if this Locale has been
0779: * removed from its VirtualUniverse.
0780: *
0781: * @see BranchGroup#pickAllSorted
0782: */
0783: public SceneGraphPath[] pickAllSorted(PickShape pickShape) {
0784: if (universe == null) {
0785: throw new IllegalStateException(J3dI18N
0786: .getString("Locale4"));
0787: }
0788:
0789: PickInfo[] pickInfoArr = pickAllSorted(PickInfo.PICK_BOUNDS,
0790: PickInfo.SCENEGRAPHPATH, pickShape);
0791:
0792: if (pickInfoArr == null) {
0793: return null;
0794: }
0795: SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
0796: for (int i = 0; i < sgpArr.length; i++) {
0797: sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
0798: }
0799:
0800: return sgpArr;
0801:
0802: }
0803:
0804: /**
0805: * Returns a sorted array of PickInfo references to all the pickable
0806: * items that intersect with the pickShape. Element [0] references
0807: * the item closest to <i>origin</i> of PickShape successive array
0808: * elements are further from the <i>origin</i>
0809: * The accuracy of the pick is set by the pick mode. The mode include :
0810: * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
0811: * is specified via a masked variable, flags, indicating which components are
0812: * present in each returned PickInfo object.
0813: *
0814: * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
0815: *
0816: * @param flags a mask indicating which components are present in each PickInfo object.
0817: * This is specified as one or more individual bits that are bitwise "OR"ed together to
0818: * describe the PickInfo data. The flags include :
0819: * <ul>
0820: * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
0821: * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
0822: * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
0823: * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
0824: * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
0825: * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
0826: * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
0827: * </ul>
0828: *
0829: * @param pickShape the description of this picking volume or area.
0830: *
0831: * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
0832: * ALL_GEOM_INFO.
0833: *
0834: * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
0835: * is set to PICK_GEOMETRY.
0836: *
0837: * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
0838: * nor PICK_GEOMETRY.
0839: *
0840: * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
0841: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
0842: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
0843: *
0844: * @exception IllegalArgumentException if pickShape is PickBounds
0845: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
0846: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
0847: *
0848: * @exception IllegalStateException if this Locale has been
0849: * removed from its VirtualUniverse.
0850: *
0851: * @exception CapabilityNotSetException if the mode is
0852: * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
0853: * is not set in any Geometry objects referred to by any shape
0854: * node whose bounds intersects the PickShape.
0855: *
0856: * @exception CapabilityNotSetException if flags contains any of
0857: * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
0858: * or ALL_GEOM_INFO, and the capability bits that control reading of
0859: * coordinate data are not set in any GeometryArray object referred
0860: * to by any shape node that intersects the PickShape.
0861: * The capability bits that must be set to avoid this exception are as follows :
0862: * <ul>
0863: * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
0864: * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
0865: * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
0866: * (in addition to one of the above)</li>
0867: * </ul>
0868: *
0869: * @see BranchGroup#pickAllSorted(int,int,javax.media.j3d.PickShape)
0870: * @see PickInfo
0871: *
0872: * @since Java 3D 1.4
0873: *
0874: */
0875: public PickInfo[] pickAllSorted(int mode, int flags,
0876: PickShape pickShape) {
0877:
0878: validateModeFlagAndPickShape(mode, flags, pickShape);
0879: GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(
0880: this , pickShape);
0881:
0882: if ((geomAtoms == null) || (geomAtoms.length == 0)) {
0883: return null;
0884: }
0885:
0886: PickInfo[] pickInfoArr = null;
0887:
0888: if (mode == PickInfo.PICK_GEOMETRY) {
0889: // Need to have closestDistance set
0890: flags |= PickInfo.CLOSEST_DISTANCE;
0891: pickInfoArr = PickInfo.pick(this , geomAtoms, mode, flags,
0892: pickShape, PickInfo.PICK_ALL);
0893: if (pickInfoArr != null) {
0894: PickInfo.sortPickInfoArray(pickInfoArr);
0895: }
0896: } else {
0897: PickInfo.sortGeomAtoms(geomAtoms, pickShape);
0898: pickInfoArr = PickInfo.pick(this , geomAtoms, mode, flags,
0899: pickShape, PickInfo.PICK_ALL);
0900: }
0901:
0902: return pickInfoArr;
0903: }
0904:
0905: /**
0906: * Returns a SceneGraphPath which references the pickable item
0907: * which is closest to the origin of <code>pickShape</code>.
0908: * <br>
0909: * NOTE: If pickShape is of type PickBounds, the return is any
0910: * pickable node below this Locale.
0911: *
0912: * @param pickShape the description of this picking volume or area.
0913: *
0914: * @exception IllegalStateException if this Locale has been
0915: * removed from its VirtualUniverse.
0916: *
0917: * @see BranchGroup#pickClosest
0918: */
0919: public SceneGraphPath pickClosest(PickShape pickShape) {
0920: if (universe == null) {
0921: throw new IllegalStateException(J3dI18N
0922: .getString("Locale4"));
0923: }
0924:
0925: PickInfo pickInfo = pickClosest(PickInfo.PICK_BOUNDS,
0926: PickInfo.SCENEGRAPHPATH, pickShape);
0927:
0928: if (pickInfo == null) {
0929: return null;
0930: }
0931: return pickInfo.getSceneGraphPath();
0932: }
0933:
0934: /**
0935: * Returns a PickInfo which references the pickable item
0936: * which is closest to the origin of <code>pickShape</code>.
0937: * The accuracy of the pick is set by the pick mode. The mode include :
0938: * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
0939: * is specified via a masked variable, flags, indicating which components are
0940: * present in each returned PickInfo object.
0941: *
0942: * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
0943: *
0944: * @param flags a mask indicating which components are present in each PickInfo object.
0945: * This is specified as one or more individual bits that are bitwise "OR"ed together to
0946: * describe the PickInfo data. The flags include :
0947: * <ul>
0948: * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
0949: * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
0950: * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
0951: * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
0952: * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
0953: * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
0954: * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
0955: * </ul>
0956: *
0957: * @param pickShape the description of this picking volume or area.
0958: *
0959: * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
0960: * ALL_GEOM_INFO.
0961: *
0962: * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
0963: * is set to PICK_GEOMETRY.
0964: *
0965: * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
0966: * nor PICK_GEOMETRY.
0967: *
0968: * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
0969: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
0970: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
0971: *
0972: * @exception IllegalArgumentException if pickShape is PickBounds
0973: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
0974: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
0975: *
0976: * @exception IllegalStateException if this Locale has been
0977: * removed from its VirtualUniverse.
0978: *
0979: * @exception CapabilityNotSetException if the mode is
0980: * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
0981: * is not set in any Geometry objects referred to by any shape
0982: * node whose bounds intersects the PickShape.
0983: *
0984: * @exception CapabilityNotSetException if flags contains any of
0985: * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
0986: * or ALL_GEOM_INFO, and the capability bits that control reading of
0987: * coordinate data are not set in any GeometryArray object referred
0988: * to by any shape node that intersects the PickShape.
0989: * The capability bits that must be set to avoid this exception are as follows :
0990: * <ul>
0991: * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
0992: * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
0993: * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
0994: * (in addition to one of the above)</li>
0995: * </ul>
0996: *
0997: * @see BranchGroup#pickClosest(int,int,javax.media.j3d.PickShape)
0998: * @see PickInfo
0999: *
1000: * @since Java 3D 1.4
1001: *
1002: */
1003: public PickInfo pickClosest(int mode, int flags, PickShape pickShape) {
1004:
1005: PickInfo[] pickInfoArr = null;
1006:
1007: pickInfoArr = pickAllSorted(mode, flags, pickShape);
1008:
1009: if (pickInfoArr == null) {
1010: return null;
1011: }
1012:
1013: return pickInfoArr[0];
1014:
1015: }
1016:
1017: /**
1018: * Returns a reference to any item that is Pickable below this
1019: * Locale which intersects with <code>pickShape</code>.
1020: *
1021: * @param pickShape the description of this picking volume or area.
1022: *
1023: * @exception IllegalStateException if this Locale has been
1024: * removed from its VirtualUniverse.
1025: *
1026: * @see BranchGroup#pickAny
1027: */
1028: public SceneGraphPath pickAny(PickShape pickShape) {
1029: if (universe == null) {
1030: throw new IllegalStateException(J3dI18N
1031: .getString("Locale4"));
1032: }
1033:
1034: PickInfo pickInfo = pickAny(PickInfo.PICK_BOUNDS,
1035: PickInfo.SCENEGRAPHPATH, pickShape);
1036:
1037: if (pickInfo == null) {
1038: return null;
1039: }
1040: return pickInfo.getSceneGraphPath();
1041:
1042: }
1043:
1044: /**
1045: * Returns a PickInfo which references the pickable item below this
1046: * Locale which intersects with <code>pickShape</code>.
1047: * The accuracy of the pick is set by the pick mode. The mode include :
1048: * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
1049: * is specified via a masked variable, flags, indicating which components are
1050: * present in each returned PickInfo object.
1051: *
1052: * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
1053: *
1054: * @param flags a mask indicating which components are present in each PickInfo object.
1055: * This is specified as one or more individual bits that are bitwise "OR"ed together to
1056: * describe the PickInfo data. The flags include :
1057: * <ul>
1058: * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
1059: * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
1060: * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
1061: * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
1062: * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
1063: * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
1064: * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
1065: * </ul>
1066: *
1067: * @param pickShape the description of this picking volume or area.
1068: *
1069: * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
1070: * ALL_GEOM_INFO.
1071: *
1072: * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
1073: * is set to PICK_GEOMETRY.
1074: *
1075: * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
1076: * nor PICK_GEOMETRY.
1077: *
1078: * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
1079: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
1080: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
1081: *
1082: * @exception IllegalArgumentException if pickShape is PickBounds
1083: * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
1084: * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
1085: *
1086: * @exception IllegalStateException if this Locale has been
1087: * removed from its VirtualUniverse.
1088: *
1089: * @exception CapabilityNotSetException if the mode is
1090: * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
1091: * is not set in any Geometry objects referred to by any shape
1092: * node whose bounds intersects the PickShape.
1093: *
1094: * @exception CapabilityNotSetException if flags contains any of
1095: * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
1096: * or ALL_GEOM_INFO, and the capability bits that control reading of
1097: * coordinate data are not set in any GeometryArray object referred
1098: * to by any shape node that intersects the PickShape.
1099: * The capability bits that must be set to avoid this exception are as follows :
1100: * <ul>
1101: * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
1102: * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
1103: * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
1104: * (in addition to one of the above)</li>
1105: * </ul>
1106: *
1107: * @see BranchGroup#pickAny(int,int,javax.media.j3d.PickShape)
1108: * @see PickInfo
1109: *
1110: * @since Java 3D 1.4
1111: *
1112: */
1113: public PickInfo pickAny(int mode, int flags, PickShape pickShape) {
1114:
1115: validateModeFlagAndPickShape(mode, flags, pickShape);
1116: GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(
1117: this , pickShape);
1118:
1119: PickInfo[] pickInfoArr = PickInfo.pick(this , geomAtoms, mode,
1120: flags, pickShape, PickInfo.PICK_ANY);
1121:
1122: if (pickInfoArr == null) {
1123: return null;
1124: }
1125:
1126: return pickInfoArr[0];
1127:
1128: }
1129:
1130: }
|