Source Code Cross Referenced for PickTool.java in  » 6.0-JDK-Modules » java-3d » com » sun » j3d » utils » picking » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » com.sun.j3d.utils.picking 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: PickTool.java,v $
0003:         *
0004:         * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         *
0010:         * - Redistribution of source code must retain the above copyright
0011:         *   notice, this list of conditions and the following disclaimer.
0012:         *
0013:         * - Redistribution in binary form must reproduce the above copyright
0014:         *   notice, this list of conditions and the following disclaimer in
0015:         *   the documentation and/or other materials provided with the
0016:         *   distribution.
0017:         *
0018:         * Neither the name of Sun Microsystems, Inc. or the names of
0019:         * contributors may be used to endorse or promote products derived
0020:         * from this software without specific prior written permission.
0021:         *
0022:         * This software is provided "AS IS," without a warranty of any
0023:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
0024:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
0025:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
0026:         * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
0027:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
0028:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
0029:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
0030:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
0031:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
0032:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
0033:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
0034:         * POSSIBILITY OF SUCH DAMAGES.
0035:         *
0036:         * You acknowledge that this software is not designed, licensed or
0037:         * intended for use in the design, construction, operation or
0038:         * maintenance of any nuclear facility.
0039:         *
0040:         * $Revision: 1.7 $
0041:         * $Date: 2007/02/09 17:20:26 $
0042:         * $State: Exp $
0043:         */
0044:
0045:        package com.sun.j3d.utils.picking;
0046:
0047:        import javax.vecmath.*;
0048:        import javax.media.j3d.*;
0049:        import com.sun.j3d.internal.*;
0050:
0051:        /** 
0052:         * The base class for picking operations.
0053:         * The picking methods will return a PickResult object for each object picked, 
0054:         * which can then be queried to 
0055:         * obtain more detailed information about the specific objects that were
0056:         * picked. 
0057:         * <p>
0058:         * The pick mode specifies the detail level of picking before the PickResult
0059:         * is returned:
0060:         * <p>
0061:         * <UL>
0062:         * <LI> PickTool.BOUNDS - Pick using the bounds of the pickable nodes.  The 
0063:         * PickResult returned will contain the SceneGraphPath to the picked Node.
0064:         * </LI>
0065:         * <LI> PickTool.GEOMETRY will pick using the geometry of the pickable nodes.
0066:         * The PickResult returned will contain the SceneGraphPath to the picked Node.
0067:         * Geometry nodes in the scene must have the ALLOW_INTERSECT capability set for
0068:         * this mode.</LI>
0069:         * <LI> PickTool.GEOMETRY_INTERSECT_INFO -is the same as GEOMETRY, but the 
0070:         * the PickResult will also include information on each intersection
0071:         * of the pick shape with the geometry.  The intersection information includes
0072:         * the sub-primitive picked (that is, the point, line, triangle or quad), 
0073:         * the closest vertex to the center of the pick shape, and 
0074:         * the intersection's coordinate, normal, color and texture coordinates.
0075:         * To allow this information to be generated, Shape3D and Morph nodes must have 
0076:         * the ALLOW_GEOMETRY_READ capability set and GeometryArrays must have the 
0077:         * ALLOW_FORMAT_READ,
0078:         * ALLOW_COUNT_READ, and ALLOW_COORDINATE_READ capabilities set, plus the
0079:         * ALLOW_COORDINATE_INDEX_READ capability for indexed geometry. 
0080:         * To inquire
0081:         * the intersection color, normal or texture coordinates 
0082:         * the corresponding READ capability bits must be set on the GeometryArray.
0083:         * </LI>
0084:         * </UL>
0085:         * <p> The utility method 
0086:         * <A HREF="PickTool.html#setCapabilities(javax.media.j3d.Node, int)">
0087:         * <code>PickTool.setCapabilities(Node, int)</code></A> 
0088:         * can be used before the scene graph is
0089:         * made live to set the 
0090:         * capabilities of Shape3D, Morph or Geometry
0091:         * nodes to allow picking.
0092:         * <p>
0093:         * A PickResult from a lower level of detail pick can be used to
0094:         * inquire more detailed information if the capibility bits are set.  
0095:         * This can be used to filter the PickResults
0096:         * before the more computationally intensive intersection processing. 
0097:         * For example,
0098:         * the application can do a BOUNDS pick and then selectively inquire
0099:         * intersections on some of the PickResults. This will save the effort of 
0100:         * doing intersection computation on the other PickResults.  
0101:         * However, inquiring the intersections from a GEOMETRY pick will make 
0102:         * the intersection computation happen twice, use GEOMETRY_INTERSECT_INFO
0103:         * if you want to inquire the intersection information on all the PickResults.
0104:         * <p>
0105:         * When using pickAllSorted or pickClosest methods, the picks 
0106:         * will be sorted by the distance from the start point of the pick shape to 
0107:         * the intersection point.
0108:         * <p>
0109:         * Morph nodes cannot be picked using the displayed geometry in 
0110:         * GEOMETRY_INTERSECT_INFO mode due to limitations in the current Java3D core 
0111:         * API (the current
0112:         * geometry of the the Morph cannot be inquired).  Instead they are picked 
0113:         * using 
0114:         * the geometry at index 0 in the Morph, this limitation may be eliminated in a
0115:         * future release of Java3D.
0116:         * <p>
0117:         * If the pick shape is a PickBounds, the pick result will contain only the
0118:         * scene graph path, even if the mode is GEOMETRY_INTERSECT_INFO.
0119:         */
0120:        public class PickTool {
0121:
0122:            /* OPEN ISSUES:
0123:               -- pickClosest() and pickAllSorted() using GEOMETRY and a non-PickRay
0124:              shape => unsorted picking.
0125:               -- Need to implement Morph geometry index 0 picking.
0126:             */
0127:
0128:            private final boolean debug = true;
0129:            protected boolean userDefineShape = false;
0130:
0131:            PickShape pickShape;
0132:
0133:            /** Used to store the BranchGroup used for picking */
0134:            BranchGroup pickRootBG = null;
0135:            /** Used to store the Locale used for picking */
0136:            Locale pickRootL = null;
0137:
0138:            /** Used to store a reference point used in determining how "close" points
0139:                are. 
0140:             */
0141:            Point3d start = null;
0142:
0143:            /* pick mode, one of BOUNDS, GEOMETRY, etc. */
0144:            int mode = BOUNDS;
0145:
0146:            /** Use this mode to pick by bounds and get basic information
0147:                on the pick. 
0148:             */
0149:            public static final int BOUNDS = 0x200;
0150:
0151:            /** Use this mode to pick by geometry and get basic 
0152:            information on the pick. 
0153:             */
0154:            public static final int GEOMETRY = 0x100;
0155:
0156:            /** Use this mode to pick by geometry and save 
0157:                information about the intersections (intersected primitive,
0158:            intersection point and closest vertex).
0159:             */
0160:            public static final int GEOMETRY_INTERSECT_INFO = 0x400;
0161:
0162:            // Flags for the setCapabilities() method
0163:            /**
0164:             * Flag to pass to <CODE>setCapabilities(Node, int)<code> to set
0165:             * the Node's capabilities to allow intersection tests, but not
0166:             * inquire information about the intersections (use for GEOMETRY mode).
0167:             * @see PickTool#setCapabilities 
0168:             */
0169:            public static final int INTERSECT_TEST = 0x1001;
0170:
0171:            /**
0172:             * Flag to pass to <CODE>setCapabilities(Node, int)<code> to set
0173:             * the Node's capabilities to allow inquiry of the intersection
0174:             * coordinate information. 
0175:             * @see PickTool#setCapabilities 
0176:             */
0177:            public static final int INTERSECT_COORD = 0x1002;
0178:
0179:            /**
0180:             * Flag to pass to <CODE>setCapabilities(Node, int)<code> to set
0181:             * the Node's capabilities to allow inquiry of all intersection
0182:             * information.
0183:             * @see PickTool#setCapabilities 
0184:             */
0185:            public static final int INTERSECT_FULL = 0x1004;
0186:
0187:            /* ============================ METHODS ============================ */
0188:
0189:            /** 
0190:             * Constructor with BranchGroup to be picked.
0191:             */
0192:            public PickTool(BranchGroup b) {
0193:                pickRootBG = b;
0194:            }
0195:
0196:            /** Returns the BranchGroup to be picked if the tool was initialized
0197:            with a BranchGroup, null otherwise. 
0198:             */
0199:            public BranchGroup getBranchGroup() {
0200:                return pickRootBG;
0201:            }
0202:
0203:            /** 
0204:             * Constructor with the Locale to be picked.
0205:             */
0206:            public PickTool(Locale l) {
0207:                pickRootL = l;
0208:            }
0209:
0210:            /** 
0211:             * Returns the Locale to be picked if the tool was initialized with
0212:             * a Locale, null otherwise.
0213:             */
0214:            public Locale getLocale() {
0215:                return pickRootL;
0216:            }
0217:
0218:            /** 
0219:             * @deprecated This method does nothing other than return its
0220:             * input parameter.
0221:             */
0222:            public Locale setBranchGroup(Locale l) {
0223:                return l;
0224:            }
0225:
0226:            /** 
0227:             * Sets the capabilities on the Node and it's components to allow
0228:             * picking at the specified detail level.  
0229:             * <p> 
0230:             * Note that by default all com.sun.j3d.utils.geometry.Primitive
0231:             * objects with the same parameters share their geometry (e.g.,
0232:             * you can have 50 spheres in your scene, but the geometry is
0233:             * stored only once).  Therefore the capabilities of the geometry
0234:             * are also shared, and once a shared node is live, the
0235:             * capabilities cannot be changed.  To assign capabilities to
0236:             * Primitives with the same parameters, either set the
0237:             * capabilities before the primitive is set live, or specify the
0238:             * Primitive.GEOMETRY_NOT_SHARED constructor parameter when
0239:             * creating the primitive.
0240:             * @param node The node to modify
0241:             * @param level The capability level, must be one of INTERSECT_TEST,
0242:             *  INTERSECT_COORD or INTERSECT_FULL
0243:             * @throws IllegalArgumentException if Node is not a Shape3D or Morph or
0244:             *	if the flag value is not valid.
0245:             * @throws javax.media.j3d.RestrictedAccessException if the node is part 
0246:             *  of a live or compiled scene graph.  */
0247:            static public void setCapabilities(Node node, int level) {
0248:                if (node instanceof  Morph) {
0249:                    Morph morph = (Morph) node;
0250:                    switch (level) {
0251:                    case INTERSECT_FULL:
0252:                        /* intentional fallthrough */
0253:                    case INTERSECT_COORD:
0254:                        morph.setCapability(Morph.ALLOW_GEOMETRY_ARRAY_READ);
0255:                        /* intentional fallthrough */
0256:                    case INTERSECT_TEST:
0257:                        break;
0258:                    default:
0259:                        throw new IllegalArgumentException("Improper level");
0260:                    }
0261:                    double[] weights = morph.getWeights();
0262:                    for (int i = 0; i < weights.length; i++) {
0263:                        GeometryArray ga = morph.getGeometryArray(i);
0264:                        setCapabilities(ga, level);
0265:                    }
0266:                } else if (node instanceof  Shape3D) {
0267:                    Shape3D shape = (Shape3D) node;
0268:                    switch (level) {
0269:                    case INTERSECT_FULL:
0270:                        /* intentional fallthrough */
0271:                    case INTERSECT_COORD:
0272:                        shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
0273:                        /* intentional fallthrough */
0274:                    case INTERSECT_TEST:
0275:                        break;
0276:                    default:
0277:                        throw new IllegalArgumentException("Improper level");
0278:                    }
0279:                    for (int i = 0; i < shape.numGeometries(); i++) {
0280:                        Geometry geo = shape.getGeometry(i);
0281:                        if (geo instanceof  GeometryArray) {
0282:                            setCapabilities((GeometryArray) geo, level);
0283:                        } else if (geo instanceof  CompressedGeometry) {
0284:                            setCapabilities((CompressedGeometry) geo, level);
0285:                        }
0286:                    }
0287:                } else {
0288:                    throw new IllegalArgumentException("Improper node type");
0289:                }
0290:            }
0291:
0292:            static private void setCapabilities(GeometryArray ga, int level) {
0293:                switch (level) {
0294:                case INTERSECT_FULL:
0295:                    ga.setCapability(GeometryArray.ALLOW_COLOR_READ);
0296:                    ga.setCapability(GeometryArray.ALLOW_NORMAL_READ);
0297:                    ga.setCapability(GeometryArray.ALLOW_TEXCOORD_READ);
0298:                    /* intential fallthrough */
0299:                case INTERSECT_COORD:
0300:                    ga.setCapability(GeometryArray.ALLOW_COUNT_READ);
0301:                    ga.setCapability(GeometryArray.ALLOW_FORMAT_READ);
0302:                    ga.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
0303:                    /* intential fallthrough */
0304:                case INTERSECT_TEST:
0305:                    ga.setCapability(GeometryArray.ALLOW_INTERSECT);
0306:                    break;
0307:                }
0308:                if (ga instanceof  IndexedGeometryArray) {
0309:                    setCapabilities((IndexedGeometryArray) ga, level);
0310:                }
0311:            }
0312:
0313:            static private void setCapabilities(IndexedGeometryArray iga,
0314:                    int level) {
0315:                switch (level) {
0316:                case INTERSECT_FULL:
0317:                    iga
0318:                            .setCapability(IndexedGeometryArray.ALLOW_COLOR_INDEX_READ);
0319:                    iga
0320:                            .setCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_READ);
0321:                    iga
0322:                            .setCapability(IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_READ);
0323:                    /* intential fallthrough */
0324:                case INTERSECT_COORD:
0325:                    iga
0326:                            .setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ);
0327:                    /* intential fallthrough */
0328:                case INTERSECT_TEST:
0329:                    break;
0330:                }
0331:            }
0332:
0333:            static private void setCapabilities(CompressedGeometry cg, int level) {
0334:                switch (level) {
0335:                case INTERSECT_FULL:
0336:                    /* intential fallthrough */
0337:                case INTERSECT_COORD:
0338:                    cg.setCapability(CompressedGeometry.ALLOW_GEOMETRY_READ);
0339:                    /* intential fallthrough */
0340:                case INTERSECT_TEST:
0341:                    cg.setCapability(CompressedGeometry.ALLOW_INTERSECT);
0342:                    break;
0343:                }
0344:            }
0345:
0346:            // Methods used to define the pick shape
0347:
0348:            /** Sets the pick shape to a user-provided PickShape object 
0349:             *  @param ps The pick shape to pick against.
0350:             *  @param startPt The start point to use for distance calculations
0351:             */
0352:            public void setShape(PickShape ps, Point3d startPt) {
0353:                this .pickShape = ps;
0354:                this .start = startPt;
0355:                userDefineShape = (ps != null);
0356:            }
0357:
0358:            /**  Sets the pick shape to use a user-provided Bounds object 
0359:             *  @param bounds The bounds to pick against.
0360:             *  @param startPt The start point to use for distance calculations
0361:             */
0362:            public void setShapeBounds(Bounds bounds, Point3d startPt) {
0363:                this .pickShape = (PickShape) new PickBounds(bounds);
0364:                this .start = startPt;
0365:                userDefineShape = true;
0366:            }
0367:
0368:            /** Sets the picking detail mode.  The default is BOUNDS.
0369:             * @param mode One of BOUNDS, GEOMETRY, GEOMETRY_INTERSECT_INFO, or 
0370:             * @exception IllegalArgumentException if mode is not a legal value
0371:             */
0372:            public void setMode(int mode) {
0373:                if ((mode != BOUNDS) && (mode != GEOMETRY)
0374:                        && (mode != GEOMETRY_INTERSECT_INFO)) {
0375:                    throw new java.lang.IllegalArgumentException();
0376:                }
0377:                this .mode = mode;
0378:            }
0379:
0380:            /** Gets the picking detail mode.
0381:             */
0382:            public int getMode() {
0383:                return mode;
0384:            }
0385:
0386:            /**  Sets the pick shape to a PickRay. 
0387:             *   @param start The start of the ray
0388:             *   @param dir The direction of the ray
0389:             */
0390:            public void setShapeRay(Point3d start, Vector3d dir) {
0391:                this .pickShape = (PickShape) new PickRay(start, dir);
0392:                this .start = start;
0393:                userDefineShape = true;
0394:            }
0395:
0396:            /**  Sets the pick shape to a PickSegment.
0397:             @param start The start of the segment
0398:            p	 @param end The end of the segment
0399:             */
0400:            public void setShapeSegment(Point3d start, Point3d end) {
0401:                this .pickShape = (PickShape) new PickSegment(start, end);
0402:                this .start = start;
0403:                userDefineShape = true;
0404:            }
0405:
0406:            /**  Sets the pick shape to a capped PickCylinder 
0407:             *   @param start The start of axis of the cylinder
0408:             *   @param end The end of the axis of the cylinder
0409:             *   @param radius The radius of the cylinder
0410:             */
0411:            public void setShapeCylinderSegment(Point3d start, Point3d end,
0412:                    double radius) {
0413:                this .pickShape = (PickShape) new PickCylinderSegment(start,
0414:                        end, radius);
0415:                this .start = start;
0416:                userDefineShape = true;
0417:            }
0418:
0419:            /**  Sets the pick shape to an infinite PickCylinder.
0420:             *   @param start The start of axis of the cylinder
0421:             *   @param dir The direction of the axis of the cylinder
0422:             *   @param radius The radius of the cylinder
0423:             */
0424:            public void setShapeCylinderRay(Point3d start, Vector3d dir,
0425:                    double radius) {
0426:                this .pickShape = (PickShape) new PickCylinderRay(start, dir,
0427:                        radius);
0428:                this .start = start;
0429:                userDefineShape = true;
0430:            }
0431:
0432:            /** Sets the pick shape to a capped PickCone 
0433:             *   @param start The start of axis of the cone
0434:             *   @param end The end of the axis of the cone
0435:             *   @param angle The angle of the cone
0436:             */
0437:            public void setShapeConeSegment(Point3d start, Point3d end,
0438:                    double angle) {
0439:                this .pickShape = (PickShape) new PickConeSegment(start, end,
0440:                        angle);
0441:                this .start = start;
0442:                userDefineShape = true;
0443:            }
0444:
0445:            /**  Sets the pick shape to an infinite PickCone. 
0446:             *   @param start The start of axis of the cone
0447:             *   @param dir The direction of the axis of the cone
0448:             *   @param angle The angle of the cone
0449:             */
0450:            public void setShapeConeRay(Point3d start, Vector3d dir,
0451:                    double angle) {
0452:                this .pickShape = (PickShape) new PickConeRay(start, dir, angle);
0453:                this .start = start;
0454:                userDefineShape = true;
0455:            }
0456:
0457:            /** Returns the PickShape for this object. */
0458:            public PickShape getPickShape() {
0459:                return pickShape;
0460:            }
0461:
0462:            /** Returns the start postion used for distance measurement. */
0463:            public Point3d getStartPosition() {
0464:                return start;
0465:            }
0466:
0467:            /** Selects all the nodes that intersect the PickShape.
0468:              @return An array of <code>PickResult</code> objects which will contain 
0469:               information about the picked instances. <code>null</code> if nothing was 
0470:               picked.
0471:             */
0472:            public PickResult[] pickAll() {
0473:                PickResult[] retval = null;
0474:                switch (mode) {
0475:                case BOUNDS:
0476:                    retval = pickAll(pickShape);
0477:                    break;
0478:                case GEOMETRY:
0479:                    retval = pickGeomAll(pickShape);
0480:                    break;
0481:                case GEOMETRY_INTERSECT_INFO:
0482:                    retval = pickGeomAllIntersect(pickShape);
0483:                    break;
0484:                default:
0485:                    throw new RuntimeException("Invalid pick mode");
0486:                }
0487:                return retval;
0488:            }
0489:
0490:            /** Select one of the nodes that intersect the PickShape
0491:                @return A <code>PickResult</code> object which will contain 
0492:                 information about the picked instance. <code>null</code> if nothing 
0493:             was picked.
0494:             */
0495:            public PickResult pickAny() {
0496:                PickResult retval = null;
0497:                switch (mode) {
0498:                case BOUNDS:
0499:                    retval = pickAny(pickShape);
0500:                    break;
0501:                case GEOMETRY:
0502:                    retval = pickGeomAny(pickShape);
0503:                    break;
0504:                case GEOMETRY_INTERSECT_INFO:
0505:                    retval = pickGeomAnyIntersect(pickShape);
0506:                    break;
0507:                default:
0508:                    throw new RuntimeException("Invalid pick mode");
0509:                }
0510:                return retval;
0511:            }
0512:
0513:            /** Select all the nodes that intersect the 
0514:                PickShape, returned sorted. The "closest" object will be returned first.
0515:                See note above to see how "closest" is determined.    
0516:            <p>
0517:            @return An array of <code>PickResult</code> objects which will contain 
0518:            information 
0519:            about the picked instances. <code>null</code> if nothing was picked.
0520:             */
0521:            public PickResult[] pickAllSorted() {
0522:                PickResult[] retval = null;
0523:
0524:                // System.out.println ("PickTool.pickAllSorted.");
0525:
0526:                switch (mode) {
0527:                case BOUNDS:
0528:                    // System.out.println ("PickTool.pickAllSorted : Bounds");
0529:                    retval = pickAllSorted(pickShape);
0530:                    break;
0531:                case GEOMETRY:
0532:                    // System.out.println ("PickTool.pickAllSorted : Geometry");
0533:                    // TODO - BugId 4351050.
0534:                    // pickGeomAllSorted is broken for PickCone and PickCylinder :
0535:                    // The current Shape3D.intersect() API doesn't return the distance for
0536:                    // PickCone and PickCylinder.
0537:                    // 2) TODO - BugId 4351579.
0538:                    // pickGeomClosest is broken for multi-geometry Shape3D node :
0539:                    // The current Shape3D.intersect() API does't return the closest intersected
0540:                    // geometry.
0541:                    retval = pickGeomAllSorted(pickShape);
0542:
0543:                    break;
0544:                case GEOMETRY_INTERSECT_INFO:
0545:                    // System.out.println ("PickShape " + pickShape);
0546:                    // System.out.println ("PickTool.pickAllSorted : GEOMETRY_INTERSECT_INFO");
0547:                    retval = pickGeomAllSortedIntersect(pickShape);
0548:                    break;
0549:                default:
0550:                    throw new RuntimeException("Invalid pick mode");
0551:                }
0552:                return retval;
0553:            }
0554:
0555:            /** Select the closest node that 
0556:                intersects the PickShape. See note above to see how "closest" is 
0557:            determined.
0558:            <p>
0559:            @return A <code>PickResult</code> object which will contain 
0560:            information about the picked instance. <code>null</code> if nothing 
0561:            was picked.
0562:             */
0563:            public PickResult pickClosest() {
0564:                PickResult retval = null;
0565:                switch (mode) {
0566:                case BOUNDS:
0567:                    retval = pickClosest(pickShape);
0568:                    break;
0569:                case GEOMETRY:
0570:                    // System.out.println("pickCloset -- Geometry based picking");
0571:                    // 1) TODO - BugId 4351050.
0572:                    // pickGeomClosest is broken for PickCone and PickCylinder :
0573:                    // The current Shape3D.intersect() API doesn't return the distance for
0574:                    // PickCone and PickCylinder.
0575:                    // 2) TODO - BugId 4351579.
0576:                    // pickGeomClosest is broken for multi-geometry Shape3D node :
0577:                    // The current Shape3D.intersect() API does't return the closest intersected
0578:                    // geometry.
0579:                    retval = pickGeomClosest(pickShape);
0580:
0581:                    break;
0582:                case GEOMETRY_INTERSECT_INFO:
0583:                    // System.out.println ("PickShape " + pickShape);
0584:                    // System.out.println ("PickTool.pickClosest : GEOMETRY_INTERSECT_INFO");
0585:                    retval = pickGeomClosestIntersect(pickShape);
0586:                    break;
0587:                default:
0588:                    throw new RuntimeException("Invalid pick mode");
0589:                }
0590:                return retval;
0591:            }
0592:
0593:            private PickResult[] pickAll(PickShape pickShape) {
0594:                PickResult[] pr = null;
0595:                SceneGraphPath[] sgp = null;
0596:
0597:                if (pickRootBG != null) {
0598:                    sgp = pickRootBG.pickAll(pickShape);
0599:                } else if (pickRootL != null) {
0600:                    sgp = pickRootL.pickAll(pickShape);
0601:                }
0602:                if (sgp == null)
0603:                    return null; // no match
0604:
0605:                // Create PickResult array
0606:                pr = new PickResult[sgp.length];
0607:                for (int i = 0; i < sgp.length; i++) {
0608:                    pr[i] = new PickResult(sgp[i], pickShape);
0609:                }
0610:                return pr;
0611:            }
0612:
0613:            private PickResult[] pickAllSorted(PickShape pickShape) {
0614:                PickResult[] pr = null;
0615:                SceneGraphPath[] sgp = null;
0616:
0617:                if (pickRootBG != null) {
0618:                    sgp = pickRootBG.pickAllSorted(pickShape);
0619:                } else if (pickRootL != null) {
0620:                    sgp = pickRootL.pickAllSorted(pickShape);
0621:                }
0622:                if (sgp == null)
0623:                    return null; // no match
0624:
0625:                // Create PickResult array
0626:                pr = new PickResult[sgp.length];
0627:                for (int i = 0; i < sgp.length; i++) {
0628:                    pr[i] = new PickResult(sgp[i], pickShape);
0629:                }
0630:                return pr;
0631:            }
0632:
0633:            private PickResult pickAny(PickShape pickShape) {
0634:                PickResult pr = null;
0635:                SceneGraphPath sgp = null;
0636:
0637:                if (pickRootBG != null) {
0638:                    sgp = pickRootBG.pickAny(pickShape);
0639:                } else if (pickRootL != null) {
0640:                    sgp = pickRootL.pickAny(pickShape);
0641:                }
0642:                if (sgp == null)
0643:                    return null; // no match
0644:
0645:                // Create PickResult object
0646:                pr = new PickResult(sgp, pickShape);
0647:                return pr;
0648:            }
0649:
0650:            private PickResult pickClosest(PickShape pickShape) {
0651:                PickResult pr = null;
0652:                SceneGraphPath sgp = null;
0653:
0654:                if (pickRootBG != null) {
0655:                    sgp = pickRootBG.pickClosest(pickShape);
0656:                } else if (pickRootL != null) {
0657:                    sgp = pickRootL.pickClosest(pickShape);
0658:                }
0659:                if (sgp == null)
0660:                    return null; // no match
0661:
0662:                // Create PickResult object
0663:                pr = new PickResult(sgp, pickShape);
0664:                return pr;
0665:            }
0666:
0667:            // ================================================================
0668:            // GEOMETRY METHODS
0669:            // ================================================================
0670:
0671:            private PickResult[] pickGeomAll(PickShape pickShape) {
0672:                SceneGraphPath[] sgp = null;
0673:                Node obj[] = null;
0674:                int i, cnt = 0;
0675:
0676:                // First pass
0677:                if (pickRootBG != null) {
0678:                    sgp = pickRootBG.pickAll(pickShape);
0679:                } else if (pickRootL != null) {
0680:                    sgp = pickRootL.pickAll(pickShape);
0681:                }
0682:                if (sgp == null)
0683:                    return null; // no match
0684:
0685:                // Second pass, check to see if geometries intersected
0686:                boolean found[] = new boolean[sgp.length];
0687:
0688:                obj = new Node[sgp.length];
0689:                PickResult[] pr = new PickResult[sgp.length];
0690:                for (i = 0; i < sgp.length; i++) {
0691:                    obj[i] = sgp[i].getObject();
0692:                    pr[i] = new PickResult(sgp[i], pickShape);
0693:
0694:                    if (obj[i] instanceof  Shape3D) {
0695:                        found[i] = ((Shape3D) obj[i]).intersect(sgp[i],
0696:                                pickShape);
0697:                    } else if (obj[i] instanceof  Morph) {
0698:                        found[i] = ((Morph) obj[i])
0699:                                .intersect(sgp[i], pickShape);
0700:                    }
0701:                    if (found[i] == true)
0702:                        cnt++;
0703:                }
0704:
0705:                if (cnt == 0)
0706:                    return null; // no match
0707:
0708:                PickResult[] newpr = new PickResult[cnt];
0709:                cnt = 0; // reset for reuse.
0710:                for (i = 0; i < sgp.length; i++) {
0711:                    if (found[i] == true)
0712:                        pr[cnt++] = pr[i];
0713:                }
0714:
0715:                return pr;
0716:            }
0717:
0718:            private PickResult[] pickGeomAllSorted(PickShape pickShape) {
0719:                SceneGraphPath[] sgp = null;
0720:                Node[] obj = null;
0721:                int i, cnt = 0;
0722:                double[] dist = new double[1];
0723:
0724:                // First pass
0725:                if (pickRootBG != null) {
0726:                    sgp = pickRootBG.pickAll(pickShape);
0727:                } else if (pickRootL != null) {
0728:                    sgp = pickRootL.pickAll(pickShape);
0729:                }
0730:                if (sgp == null)
0731:                    return null; // no match
0732:
0733:                /*
0734:                  System.out.println ("PickTool.pickGeomAllSorted: bounds " +
0735:                  "picking found "+sgp.length+" nodes");
0736:                 */
0737:                // Second pass, check to see if geometries intersected
0738:                boolean[] found = new boolean[sgp.length];
0739:                double[] distArr = new double[sgp.length];
0740:                obj = new Node[sgp.length];
0741:                PickResult[] pr = new PickResult[sgp.length];
0742:
0743:                for (i = 0; i < sgp.length; i++) {
0744:                    obj[i] = sgp[i].getObject();
0745:                    pr[i] = new PickResult(sgp[i], pickShape);
0746:                    if (obj[i] instanceof  Shape3D) {
0747:                        found[i] = ((Shape3D) obj[i]).intersect(sgp[i],
0748:                                pickShape, dist);
0749:                        distArr[i] = dist[0];
0750:                    } else if (obj[i] instanceof  Morph) {
0751:                        found[i] = ((Morph) obj[i]).intersect(sgp[i],
0752:                                pickShape, dist);
0753:                        distArr[i] = dist[0];
0754:                    }
0755:                    if (found[i] == true)
0756:                        cnt++;
0757:                }
0758:                if (cnt == 0)
0759:                    return null; // no match
0760:
0761:                PickResult[] npr = new PickResult[cnt];
0762:                double[] distance = new double[cnt];
0763:                cnt = 0; // reset for reuse.
0764:                for (i = 0; i < sgp.length; i++) {
0765:                    if (found[i] == true) {
0766:                        distance[cnt] = distArr[i];
0767:                        npr[cnt++] = pr[i];
0768:                    }
0769:                }
0770:                if (cnt > 1) {
0771:                    return sortPickResults(npr, distance);
0772:                } else { // Don't have to sort if only one item
0773:                    return npr;
0774:                }
0775:            }
0776:
0777:            private PickResult pickGeomAny(PickShape pickShape) {
0778:                Node obj = null;
0779:                int i;
0780:                SceneGraphPath[] sgpa = null;
0781:
0782:                if (pickRootBG != null) {
0783:                    sgpa = pickRootBG.pickAll(pickShape);
0784:                } else if (pickRootL != null) {
0785:                    sgpa = pickRootL.pickAll(pickShape);
0786:                }
0787:
0788:                if (sgpa == null)
0789:                    return null; // no match
0790:
0791:                for (i = 0; i < sgpa.length; i++) {
0792:                    obj = sgpa[i].getObject();
0793:                    PickResult pr = new PickResult(sgpa[i], pickShape);
0794:                    if (obj instanceof  Shape3D) {
0795:                        if (((Shape3D) obj).intersect(sgpa[i], pickShape)) {
0796:                            return pr;
0797:                        }
0798:                    } else if (obj instanceof  Morph) {
0799:                        if (((Morph) obj).intersect(sgpa[i], pickShape)) {
0800:                            return pr;
0801:                        }
0802:                    }
0803:                }
0804:
0805:                return null;
0806:            }
0807:
0808:            private PickResult pickGeomClosest(PickShape pickShape) {
0809:                // System.out.println("pickGeomCloset -- Geometry based picking");
0810:                PickResult[] pr = pickGeomAllSorted(pickShape);
0811:                if (pr == null) {
0812:                    return null;
0813:                } else {
0814:                    return pr[0];
0815:                }
0816:            }
0817:
0818:            // ================================================================
0819:            // NEW METHODS, return additional information
0820:            // ================================================================
0821:
0822:            private PickResult[] pickGeomAllIntersect(PickShape pickShape) {
0823:                SceneGraphPath[] sgp = null;
0824:                Node obj[] = null;
0825:                int i, cnt = 0;
0826:
0827:                // First pass
0828:                if (pickRootBG != null) {
0829:                    sgp = pickRootBG.pickAll(pickShape);
0830:                } else if (pickRootL != null) {
0831:                    sgp = pickRootL.pickAll(pickShape);
0832:                }
0833:                if (sgp == null)
0834:                    return null; // no match
0835:
0836:                // Second pass, check to see if geometries intersected
0837:                boolean found[] = new boolean[sgp.length];
0838:
0839:                PickResult[] pr = new PickResult[sgp.length];
0840:                for (i = 0; i < sgp.length; i++) {
0841:                    pr[i] = new PickResult(sgp[i], pickShape);
0842:                    if (pr[i].numIntersections() > 0) {
0843:                        found[i] = true;
0844:                        cnt++;
0845:                    }
0846:                }
0847:
0848:                if (cnt == 0)
0849:                    return null; // no match
0850:
0851:                PickResult[] newpr = new PickResult[cnt];
0852:                cnt = 0; // reset for reuse.
0853:                for (i = 0; i < sgp.length; i++) {
0854:                    if (found[i] == true)
0855:                        pr[cnt++] = pr[i];
0856:                }
0857:
0858:                return pr;
0859:            }
0860:
0861:            private PickResult[] pickGeomAllSortedIntersect(PickShape pickShape) {
0862:                SceneGraphPath[] sgp = null;
0863:                Node[] obj = null;
0864:                int i, cnt = 0;
0865:                double[] dist = new double[1];
0866:
0867:                // First pass
0868:                if (pickRootBG != null) {
0869:                    sgp = pickRootBG.pickAll(pickShape);
0870:                } else if (pickRootL != null) {
0871:                    sgp = pickRootL.pickAll(pickShape);
0872:                }
0873:                if (sgp == null)
0874:                    return null; // no match
0875:
0876:                // System.out.println ("PickTool.pickGeomAllSortedIntersect: bounds " +
0877:                // " picking found "+sgp.length+" nodes");
0878:
0879:                // Second pass, check to see if geometries intersected
0880:                boolean[] found = new boolean[sgp.length];
0881:                double[] distArr = new double[sgp.length];
0882:
0883:                PickResult[] pr = new PickResult[sgp.length];
0884:                for (i = 0; i < sgp.length; i++) {
0885:                    pr[i] = new PickResult(sgp[i], pickShape);
0886:                    int numIntersection = pr[i].numIntersections();
0887:                    if (numIntersection > 0) {
0888:                        // System.out.println ("numIntersection " + numIntersection);
0889:                        found[i] = true;
0890:                        double minDist;
0891:                        double tempDist;
0892:
0893:                        int minIndex;
0894:                        boolean needToSwap = false;
0895:                        minDist = pr[i].getIntersection(0).getDistance();
0896:                        minIndex = 0;
0897:                        for (int j = 1; j < numIntersection; j++) {
0898:                            // System.out.println ("Distance " + pr[i].getIntersection(j).getDistance());
0899:                            //System.out.println ("Geom Index " + pr[i].getIntersection(j).getGeometryArrayIndex());
0900:                            tempDist = pr[i].getIntersection(j).getDistance();
0901:                            if (minDist > tempDist) {
0902:                                minDist = tempDist;
0903:                                minIndex = j;
0904:                                needToSwap = true;
0905:                            }
0906:                        }
0907:
0908:                        //Swap if necc.
0909:                        if (needToSwap) {
0910:                            // System.out.println ("Swap is needed");
0911:                            PickIntersection pi0 = pr[i].getIntersection(0);
0912:                            PickIntersection piMin = pr[i]
0913:                                    .getIntersection(minIndex);
0914:                            pr[i].intersections.set(0, piMin);
0915:                            pr[i].intersections.set(minIndex, pi0);
0916:                        }
0917:
0918:                        distArr[i] = pr[i].getIntersection(0).getDistance();
0919:                        cnt++;
0920:                    }
0921:                }
0922:
0923:                // System.out.println ("PickTool.pickGeomAllSortedIntersect: geometry intersect check "
0924:                // + " cnt " + cnt);
0925:
0926:                if (cnt == 0)
0927:                    return null; // no match
0928:
0929:                PickResult[] npr = new PickResult[cnt];
0930:                double[] distance = new double[cnt];
0931:                cnt = 0; // reset for reuse.
0932:                for (i = 0; i < sgp.length; i++) {
0933:                    if (found[i] == true) {
0934:                        distance[cnt] = distArr[i];
0935:                        npr[cnt++] = pr[i];
0936:                    }
0937:                }
0938:
0939:                if (cnt > 1) {
0940:                    return sortPickResults(npr, distance);
0941:                } else { // Don't have to sort if only one item
0942:                    return npr;
0943:                }
0944:            }
0945:
0946:            private PickResult pickGeomClosestIntersect(PickShape pickShape) {
0947:                PickResult[] pr = pickGeomAllSortedIntersect(pickShape);
0948:                /*
0949:                  System.out.println ("PickTool.pickGeomClosestIntersect: pr.length "
0950:                  + pr.length);
0951:                  for(int i=0;i<pr.length;i++) {
0952:                  System.out.println ("pr["+i+"] " + pr[i]);
0953:                  }
0954:                 */
0955:
0956:                if (pr == null) {
0957:                    return null;
0958:                } else {
0959:                    return pr[0];
0960:                }
0961:            }
0962:
0963:            private PickResult pickGeomAnyIntersect(PickShape pickShape) {
0964:                Node obj = null;
0965:                int i;
0966:                SceneGraphPath[] sgpa = null;
0967:
0968:                if (pickRootBG != null) {
0969:                    sgpa = pickRootBG.pickAll(pickShape);
0970:                } else if (pickRootL != null) {
0971:                    sgpa = pickRootL.pickAll(pickShape);
0972:                }
0973:                if (sgpa == null)
0974:                    return null; // no match
0975:                for (i = 0; i < sgpa.length; i++) {
0976:                    PickResult pr = new PickResult(sgpa[i], pickShape);
0977:                    pr.setFirstIntersectOnly(true);
0978:                    if (pr.numIntersections() > 0) {
0979:                        return pr;
0980:                    }
0981:                }
0982:
0983:                return null;
0984:            }
0985:
0986:            // ================================================================
0987:            // Sort Methods
0988:            // ================================================================
0989:            private PickResult[] sortPickResults(PickResult[] pr, double[] dist) {
0990:                int[] pos = new int[pr.length];
0991:                PickResult[] prsorted = new PickResult[pr.length];
0992:
0993:                // Initialize position array
0994:                for (int i = 0; i < pr.length; i++) {
0995:                    pos[i] = i;
0996:                }
0997:                // Do sort
0998:                quicksort(0, dist.length - 1, dist, pos);
0999:
1000:                // Create new array
1001:                for (int i = 0; i < pr.length; i++) {
1002:                    prsorted[i] = pr[pos[i]];
1003:                }
1004:                return prsorted;
1005:            }
1006:
1007:            private final void quicksort(int l, int r, double[] dist, int[] pos) {
1008:                int p, i, j;
1009:                double tmp, k;
1010:
1011:                i = l;
1012:                j = r;
1013:                k = dist[(l + r) / 2];
1014:                do {
1015:                    while (dist[i] < k)
1016:                        i++;
1017:                    while (k < dist[j])
1018:                        j--;
1019:                    if (i <= j) {
1020:                        tmp = dist[i];
1021:                        dist[i] = dist[j];
1022:                        dist[j] = tmp;
1023:
1024:                        p = pos[i];
1025:                        pos[i] = pos[j];
1026:                        pos[j] = p;
1027:                        i++;
1028:                        j--;
1029:                    }
1030:                } while (i <= j);
1031:
1032:                if (l < j)
1033:                    quicksort(l, j, dist, pos);
1034:                if (l < r)
1035:                    quicksort(i, r, dist, pos);
1036:            }
1037:
1038:        } // PickTool
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.