📄 picktool.java
字号:
/* * $RCSfile: PickTool.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. * * $Revision: 1.7 $ * $Date: 2007/02/09 17:20:26 $ * $State: Exp $ */package com.sun.j3d.utils.picking;import javax.vecmath.*;import javax.media.j3d.*;import com.sun.j3d.internal.*;/** * The base class for picking operations. * The picking methods will return a PickResult object for each object picked, * which can then be queried to * obtain more detailed information about the specific objects that were * picked. * <p> * The pick mode specifies the detail level of picking before the PickResult * is returned: * <p> * <UL> * <LI> PickTool.BOUNDS - Pick using the bounds of the pickable nodes. The * PickResult returned will contain the SceneGraphPath to the picked Node. * </LI> * <LI> PickTool.GEOMETRY will pick using the geometry of the pickable nodes. * The PickResult returned will contain the SceneGraphPath to the picked Node. * Geometry nodes in the scene must have the ALLOW_INTERSECT capability set for * this mode.</LI> * <LI> PickTool.GEOMETRY_INTERSECT_INFO -is the same as GEOMETRY, but the * the PickResult will also include information on each intersection * of the pick shape with the geometry. The intersection information includes * the sub-primitive picked (that is, the point, line, triangle or quad), * the closest vertex to the center of the pick shape, and * the intersection's coordinate, normal, color and texture coordinates. * To allow this information to be generated, Shape3D and Morph nodes must have * the ALLOW_GEOMETRY_READ capability set and GeometryArrays must have the * ALLOW_FORMAT_READ, * ALLOW_COUNT_READ, and ALLOW_COORDINATE_READ capabilities set, plus the * ALLOW_COORDINATE_INDEX_READ capability for indexed geometry. * To inquire * the intersection color, normal or texture coordinates * the corresponding READ capability bits must be set on the GeometryArray. * </LI> * </UL> * <p> The utility method * <A HREF="PickTool.html#setCapabilities(javax.media.j3d.Node, int)"> * <code>PickTool.setCapabilities(Node, int)</code></A> * can be used before the scene graph is * made live to set the * capabilities of Shape3D, Morph or Geometry * nodes to allow picking. * <p> * A PickResult from a lower level of detail pick can be used to * inquire more detailed information if the capibility bits are set. * This can be used to filter the PickResults * before the more computationally intensive intersection processing. * For example, * the application can do a BOUNDS pick and then selectively inquire * intersections on some of the PickResults. This will save the effort of * doing intersection computation on the other PickResults. * However, inquiring the intersections from a GEOMETRY pick will make * the intersection computation happen twice, use GEOMETRY_INTERSECT_INFO * if you want to inquire the intersection information on all the PickResults. * <p> * When using pickAllSorted or pickClosest methods, the picks * will be sorted by the distance from the start point of the pick shape to * the intersection point. * <p> * Morph nodes cannot be picked using the displayed geometry in * GEOMETRY_INTERSECT_INFO mode due to limitations in the current Java3D core * API (the current * geometry of the the Morph cannot be inquired). Instead they are picked * using * the geometry at index 0 in the Morph, this limitation may be eliminated in a * future release of Java3D. * <p> * If the pick shape is a PickBounds, the pick result will contain only the * scene graph path, even if the mode is GEOMETRY_INTERSECT_INFO. */public class PickTool { /* OPEN ISSUES: -- pickClosest() and pickAllSorted() using GEOMETRY and a non-PickRay shape => unsorted picking. -- Need to implement Morph geometry index 0 picking. */ private final boolean debug = true; protected boolean userDefineShape = false; PickShape pickShape; /** Used to store the BranchGroup used for picking */ BranchGroup pickRootBG = null; /** Used to store the Locale used for picking */ Locale pickRootL = null; /** Used to store a reference point used in determining how "close" points are. */ Point3d start = null; /* pick mode, one of BOUNDS, GEOMETRY, etc. */ int mode = BOUNDS; /** Use this mode to pick by bounds and get basic information on the pick. */ public static final int BOUNDS = 0x200; /** Use this mode to pick by geometry and get basic information on the pick. */ public static final int GEOMETRY = 0x100; /** Use this mode to pick by geometry and save information about the intersections (intersected primitive, intersection point and closest vertex). */ public static final int GEOMETRY_INTERSECT_INFO = 0x400; // Flags for the setCapabilities() method /** * Flag to pass to <CODE>setCapabilities(Node, int)<code> to set * the Node's capabilities to allow intersection tests, but not * inquire information about the intersections (use for GEOMETRY mode). * @see PickTool#setCapabilities */ public static final int INTERSECT_TEST = 0x1001; /** * Flag to pass to <CODE>setCapabilities(Node, int)<code> to set * the Node's capabilities to allow inquiry of the intersection * coordinate information. * @see PickTool#setCapabilities */ public static final int INTERSECT_COORD = 0x1002; /** * Flag to pass to <CODE>setCapabilities(Node, int)<code> to set * the Node's capabilities to allow inquiry of all intersection * information. * @see PickTool#setCapabilities */ public static final int INTERSECT_FULL = 0x1004; /* ============================ METHODS ============================ */ /** * Constructor with BranchGroup to be picked. */ public PickTool (BranchGroup b) { pickRootBG = b; } /** Returns the BranchGroup to be picked if the tool was initialized with a BranchGroup, null otherwise. */ public BranchGroup getBranchGroup() { return pickRootBG; } /** * Constructor with the Locale to be picked. */ public PickTool (Locale l) { pickRootL = l; } /** * Returns the Locale to be picked if the tool was initialized with * a Locale, null otherwise. */ public Locale getLocale () { return pickRootL; } /** * @deprecated This method does nothing other than return its * input parameter. */ public Locale setBranchGroup (Locale l) { return l; } /** * Sets the capabilities on the Node and it's components to allow * picking at the specified detail level. * <p> * Note that by default all com.sun.j3d.utils.geometry.Primitive * objects with the same parameters share their geometry (e.g., * you can have 50 spheres in your scene, but the geometry is * stored only once). Therefore the capabilities of the geometry * are also shared, and once a shared node is live, the * capabilities cannot be changed. To assign capabilities to * Primitives with the same parameters, either set the * capabilities before the primitive is set live, or specify the * Primitive.GEOMETRY_NOT_SHARED constructor parameter when * creating the primitive. * @param node The node to modify * @param level The capability level, must be one of INTERSECT_TEST, * INTERSECT_COORD or INTERSECT_FULL * @throws IllegalArgumentException if Node is not a Shape3D or Morph or * if the flag value is not valid. * @throws javax.media.j3d.RestrictedAccessException if the node is part * of a live or compiled scene graph. */ static public void setCapabilities(Node node, int level) { if (node instanceof Morph) { Morph morph = (Morph) node; switch (level) { case INTERSECT_FULL: /* intentional fallthrough */ case INTERSECT_COORD: morph.setCapability(Morph.ALLOW_GEOMETRY_ARRAY_READ); /* intentional fallthrough */ case INTERSECT_TEST: break; default: throw new IllegalArgumentException("Improper level"); } double[] weights = morph.getWeights(); for (int i = 0; i < weights.length; i++) { GeometryArray ga = morph.getGeometryArray(i); setCapabilities(ga, level); } } else if (node instanceof Shape3D) { Shape3D shape = (Shape3D) node; switch (level) { case INTERSECT_FULL: /* intentional fallthrough */ case INTERSECT_COORD: shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); /* intentional fallthrough */ case INTERSECT_TEST: break; default: throw new IllegalArgumentException("Improper level"); } for (int i = 0; i < shape.numGeometries(); i++) { Geometry geo = shape.getGeometry(i); if (geo instanceof GeometryArray) { setCapabilities((GeometryArray)geo, level); } else if (geo instanceof CompressedGeometry) { setCapabilities((CompressedGeometry)geo, level); } } } else { throw new IllegalArgumentException("Improper node type"); } } static private void setCapabilities(GeometryArray ga, int level) { switch (level) { case INTERSECT_FULL: ga.setCapability(GeometryArray.ALLOW_COLOR_READ); ga.setCapability(GeometryArray.ALLOW_NORMAL_READ); ga.setCapability(GeometryArray.ALLOW_TEXCOORD_READ); /* intential fallthrough */ case INTERSECT_COORD: ga.setCapability(GeometryArray.ALLOW_COUNT_READ); ga.setCapability(GeometryArray.ALLOW_FORMAT_READ); ga.setCapability(GeometryArray.ALLOW_COORDINATE_READ); /* intential fallthrough */ case INTERSECT_TEST: ga.setCapability(GeometryArray.ALLOW_INTERSECT); break; } if (ga instanceof IndexedGeometryArray) { setCapabilities((IndexedGeometryArray)ga, level); } } static private void setCapabilities(IndexedGeometryArray iga, int level) { switch (level) { case INTERSECT_FULL: iga.setCapability(IndexedGeometryArray.ALLOW_COLOR_INDEX_READ); iga.setCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_READ); iga.setCapability(IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_READ); /* intential fallthrough */ case INTERSECT_COORD: iga.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ); /* intential fallthrough */ case INTERSECT_TEST: break; } } static private void setCapabilities(CompressedGeometry cg, int level) { switch (level) { case INTERSECT_FULL: /* intential fallthrough */ case INTERSECT_COORD: cg.setCapability(CompressedGeometry.ALLOW_GEOMETRY_READ); /* intential fallthrough */ case INTERSECT_TEST: cg.setCapability(CompressedGeometry.ALLOW_INTERSECT); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -