Source Code Cross Referenced for PickIntersection.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: PickIntersection.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.5 $
0041:         * $Date: 2007/03/02 21:27:15 $
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.utils.geometry.Primitive;
0050:
0051:        /**
0052:         * Holds information about an intersection of a PickShape with a Node 
0053:         * as part of a PickResult. Information about
0054:         * the intersected geometry, intersected primitive, intersection point, and 
0055:         * closest vertex can be inquired.  
0056:         * <p>
0057:         * The intersected geometry is indicated by an index into the list of 
0058:         * geometry arrays on the PickResult.  It can also be inquired from this
0059:         * object.
0060:         * <p>
0061:         * The intersected primitive indicates which primitive out of the GeometryArray
0062:         * was intersected (where the primitive is a point, line, triangle or quad, 
0063:         * not a
0064:         * <code>com.sun.j3d.utils.geometry.Primitive)</code>.  
0065:         * For example, the intersection would indicate which triangle out of a 
0066:         * triangle strip was intersected.
0067:         * The methods which return primitive data will have one value if the primitive 
0068:         * is
0069:         * a point, two values if the primitive is a line, three values if the primitive
0070:         * is a triangle and four values if the primitive is quad.
0071:         * <p>
0072:         * The primitive's VWorld coordinates are saved when then intersection is 
0073:         * calculated.  The local coordinates, normal, color and texture coordinates
0074:         * for the primitive can also be inquired if they are present and readable.
0075:         * <p>
0076:         * The intersection point is the location on the primitive which intersects the
0077:         * pick shape closest to the center of the pick shape. The intersection point's
0078:         * location in VWorld coordinates is saved when the intersection is calculated.
0079:         * The local coordinates, normal, color and texture coordiantes of at the
0080:         * intersection can be interpolated if they are present and readable.
0081:         * <p>
0082:         * The closest vertex is the vertex of the primitive closest to the intersection
0083:         * point.  The vertex index, VWorld coordinates and local coordinates of the 
0084:         * closest vertex can be inquired.  The normal, color and texture coordinate
0085:         * of the closest vertex can be inquired from the geometry array:
0086:         * <p><blockquote><pre>
0087:         *      Vector3f getNormal(PickIntersection pi, int vertexIndex) {
0088:         *          int index;
0089:         *          Vector3d normal = new Vector3f();
0090:         *          GeometryArray ga = pickIntersection.getGeometryArray();
0091:         *          if (pickIntersection.geometryIsIndexed()) {
0092:         *              index = ga.getNormalIndex(vertexIndex);
0093:         *          } else {
0094:         *              index = vertexIndex;
0095:         *          }
0096:         *          ga.getNormal(index, normal);
0097:         *          return normal;
0098:         *      }
0099:         * </pre></blockquote>
0100:         * <p>
0101:         * The color, normal
0102:         * and texture coordinate information for the intersected primitive and the 
0103:         * intersection point
0104:         * can be inquired
0105:         * the geometry includes them and the corresponding READ capibility bits are 
0106:         * set.
0107:         * <A HREF="PickTool.html#setCapabilities(javax.media.j3d.Node, int)">
0108:         * <code>PickTool.setCapabilties(Node, int)</code></A> 
0109:         * can be used to set the capability bits
0110:         * to allow this data to be inquired.
0111:         */
0112:        public class PickIntersection {
0113:
0114:            /* OPEN ISSUES:
0115:               -- Tex coordinates always use texCoordSet == 0.
0116:             */
0117:
0118:            /* =================== ATTRIBUTES ======================= */
0119:
0120:            // init by constructor:
0121:            /** PickResult for intersection is part of */
0122:            PickResult pickResult = null;
0123:
0124:            // init by intersection:
0125:            /** Distance between start point and intersection point (see comment above)*/
0126:            double distance = -1;
0127:
0128:            /** index of GeometryArray in PickResult */
0129:            int geomIndex = 0;
0130:
0131:            /** Indices of the intersected primitive */
0132:            int[] primitiveVertexIndices = null;
0133:
0134:            /** VWorld coordinates of intersected primitive */
0135:            Point3d[] primitiveCoordinatesVW = null;
0136:
0137:            /** VWorld Coordinates of the intersection point */
0138:            Point3d pointCoordinatesVW = null;
0139:
0140:            // Derived data
0141:
0142:            // Geometry
0143:            GeometryArray geom = null;
0144:            IndexedGeometryArray iGeom = null;
0145:            boolean hasNormals = false;
0146:            boolean hasColors = false;
0147:            boolean hasTexCoords = false;
0148:
0149:            // Primitive
0150:            /* indices for the different data types */
0151:            int[] primitiveCoordinateIndices;
0152:            int[] primitiveNormalIndices;
0153:            int[] primitiveColorIndices;
0154:            int[] primitiveTexCoordIndices;
0155:
0156:            /* Local coordinates of the intersected primitive */
0157:            Point3d[] primitiveCoordinates = null;
0158:
0159:            /* Normals of the intersected primitive */
0160:            Vector3f[] primitiveNormals = null;
0161:
0162:            /* Colors of the intersected primitive */
0163:            Color4f[] primitiveColors = null;
0164:
0165:            /* TextureCoordinates of the intersected primitive */
0166:            TexCoord3f[] primitiveTexCoords = null;
0167:
0168:            // Intersection point
0169:
0170:            /** Local Coordinates of the intersection point */
0171:            Point3d pointCoordinates = null;
0172:
0173:            /** Normal at the intersection point */
0174:            Vector3f pointNormal = null;
0175:
0176:            /** Color at the intersection point */
0177:            Color4f pointColor = null;
0178:
0179:            /** TexCoord at the intersection point */
0180:            TexCoord3f pointTexCoord = null;
0181:
0182:            // Closest Vertex
0183:            /** Index of the closest vertex */
0184:            int closestVertexIndex = -1;
0185:
0186:            /** Coordinates of the closest vertex */
0187:            Point3d closestVertexCoordinates = null;
0188:
0189:            /** Coordinates of the closest vertex (World coordinates) */
0190:            Point3d closestVertexCoordinatesVW = null;
0191:
0192:            /** Weight factors for interpolation, values correspond to vertex indices,
0193:             * sum == 1
0194:             */
0195:            double[] interpWeights;
0196:
0197:            static final boolean debug = false;
0198:
0199:            // Axis constants
0200:            static final int X_AXIS = 1;
0201:            static final int Y_AXIS = 2;
0202:            static final int Z_AXIS = 3;
0203:
0204:            // Tolerance for numerical stability
0205:            static final double TOL = 1.0e-5;
0206:
0207:            /* ===================   METHODS  ======================= */
0208:
0209:            /** Constructor 
0210:              @param pickResult The pickResult this intersection is part of.
0211:             */
0212:            PickIntersection(PickResult pr, GeometryArray geomArr) {
0213:
0214:                // pr can't be null.
0215:                pickResult = pr;
0216:                geom = geomArr;
0217:                if (geom == null) {
0218:                    GeometryArray[] ga = pickResult.getGeometryArrays();
0219:                    geom = ga[geomIndex];
0220:
0221:                }
0222:
0223:                if (geom instanceof  IndexedGeometryArray) {
0224:                    iGeom = (IndexedGeometryArray) geom;
0225:                }
0226:                int vertexFormat = geom.getVertexFormat();
0227:                hasColors = (0 != (vertexFormat & (GeometryArray.COLOR_3 | GeometryArray.COLOR_4)));
0228:                hasNormals = (0 != (vertexFormat & GeometryArray.NORMALS));
0229:                hasTexCoords = (0 != (vertexFormat & (GeometryArray.TEXTURE_COORDINATE_2 | GeometryArray.TEXTURE_COORDINATE_3)));
0230:            }
0231:
0232:            /**
0233:              String representation of this object
0234:             */
0235:            public String toString() {
0236:                String rt = new String("PickIntersection: ");
0237:                rt += " pickResult = " + pickResult + "\n";
0238:                rt += " geomIndex = " + geomIndex + "\n";
0239:                if (distance != -1)
0240:                    rt += " dist:" + distance + "\n";
0241:                if (pointCoordinates != null)
0242:                    rt += " pt:" + pointCoordinates + "\n";
0243:                if (pointCoordinatesVW != null)
0244:                    rt += " ptVW:" + pointCoordinatesVW + "\n";
0245:
0246:                if (primitiveCoordinateIndices != null) {
0247:                    rt += " prim coordinate ind:" + "\n";
0248:                    for (int i = 0; i < primitiveCoordinateIndices.length; i++) {
0249:                        rt += " " + primitiveCoordinateIndices[i] + "\n";
0250:                    }
0251:                }
0252:
0253:                if (primitiveColorIndices != null) {
0254:                    rt += " prim color ind:" + "\n";
0255:                    for (int i = 0; i < primitiveColorIndices.length; i++) {
0256:                        rt += " " + primitiveColorIndices[i] + "\n";
0257:                    }
0258:                }
0259:
0260:                if (primitiveNormalIndices != null) {
0261:                    rt += " prim normal ind:" + "\n";
0262:                    for (int i = 0; i < primitiveNormalIndices.length; i++) {
0263:                        rt += " " + primitiveNormalIndices[i] + "\n";
0264:                    }
0265:                }
0266:
0267:                if (primitiveTexCoordIndices != null) {
0268:                    rt += " prim texture ind:" + "\n";
0269:                    for (int i = 0; i < primitiveTexCoordIndices.length; i++) {
0270:                        rt += " " + primitiveTexCoordIndices[i] + "\n";
0271:                    }
0272:                }
0273:
0274:                if (closestVertexCoordinates != null) {
0275:                    rt += " clos. vert:" + closestVertexCoordinates + "\n";
0276:                }
0277:
0278:                if (closestVertexCoordinatesVW != null) {
0279:                    rt += " clos. vert:" + closestVertexCoordinatesVW + "\n";
0280:                }
0281:
0282:                if (closestVertexIndex != -1) {
0283:                    rt += " clos. vert. ind.:" + closestVertexIndex + "\n";
0284:                }
0285:                return rt;
0286:            }
0287:
0288:            /* Call only by PickResult */
0289:            String toString2() {
0290:                String rt = new String("PickIntersection: ");
0291:                // rt += " pickResult = "+pickResult;
0292:                rt += " geomIndex = " + geomIndex + "\n";
0293:                if (distance != -1)
0294:                    rt += " dist:" + distance + "\n";
0295:                if (pointCoordinates != null)
0296:                    rt += " pt:" + pointCoordinates + "\n";
0297:                if (pointCoordinatesVW != null)
0298:                    rt += " ptVW:" + pointCoordinatesVW + "\n";
0299:
0300:                if (primitiveCoordinateIndices != null) {
0301:                    rt += " prim coordinate ind:" + "\n";
0302:                    for (int i = 0; i < primitiveCoordinateIndices.length; i++) {
0303:                        rt += " " + primitiveCoordinateIndices[i] + "\n";
0304:                    }
0305:                }
0306:
0307:                if (primitiveColorIndices != null) {
0308:                    rt += " prim color ind:" + "\n";
0309:                    for (int i = 0; i < primitiveColorIndices.length; i++) {
0310:                        rt += " " + primitiveColorIndices[i] + "\n";
0311:                    }
0312:                }
0313:
0314:                if (primitiveNormalIndices != null) {
0315:                    rt += " prim normal ind:" + "\n";
0316:                    for (int i = 0; i < primitiveNormalIndices.length; i++) {
0317:                        rt += " " + primitiveNormalIndices[i] + "\n";
0318:                    }
0319:                }
0320:
0321:                if (primitiveTexCoordIndices != null) {
0322:                    rt += " prim texture ind:" + "\n";
0323:                    for (int i = 0; i < primitiveTexCoordIndices.length; i++) {
0324:                        rt += " " + primitiveTexCoordIndices[i] + "\n";
0325:                    }
0326:                }
0327:
0328:                if (closestVertexCoordinates != null) {
0329:                    rt += " clos. vert:" + closestVertexCoordinates + "\n";
0330:                }
0331:
0332:                if (closestVertexCoordinatesVW != null) {
0333:                    rt += " clos. vert:" + closestVertexCoordinatesVW + "\n";
0334:                }
0335:
0336:                if (closestVertexIndex != -1) {
0337:                    rt += " clos. vert. ind.:" + closestVertexIndex + "\n";
0338:                }
0339:                return rt;
0340:            }
0341:
0342:            /**
0343:              Gets the PickResult this intersection is part of
0344:             */
0345:            PickResult getPickResult() {
0346:                return pickResult;
0347:            }
0348:
0349:            /**
0350:              Sets the geom index into the pick result 
0351:             */
0352:            void setGeomIndex(int gi) {
0353:
0354:                if (geomIndex != gi) {
0355:                    GeometryArray[] ga = pickResult.getGeometryArrays();
0356:                    geom = ga[gi];
0357:
0358:                    if (geom instanceof  IndexedGeometryArray) {
0359:                        iGeom = (IndexedGeometryArray) geom;
0360:                    }
0361:                    int vertexFormat = geom.getVertexFormat();
0362:                    hasColors = (0 != (vertexFormat & (GeometryArray.COLOR_3 | GeometryArray.COLOR_4)));
0363:                    hasNormals = (0 != (vertexFormat & GeometryArray.NORMALS));
0364:                    hasTexCoords = (0 != (vertexFormat & (GeometryArray.TEXTURE_COORDINATE_2 | GeometryArray.TEXTURE_COORDINATE_3)));
0365:                }
0366:
0367:                geomIndex = gi;
0368:            }
0369:
0370:            /** 
0371:              Sets the coordinates of the intersection point (world coordinates).
0372:              @param pt the coordinates
0373:             */
0374:            void setPointCoordinatesVW(Point3d pt) {
0375:                if (pointCoordinatesVW == null) {
0376:                    pointCoordinatesVW = new Point3d();
0377:                }
0378:                pointCoordinatesVW.x = pt.x;
0379:                pointCoordinatesVW.y = pt.y;
0380:                pointCoordinatesVW.z = pt.z;
0381:            }
0382:
0383:            /**
0384:              Returns the coordinates of the intersection point (world coordinates), 
0385:              if available.
0386:              @return coordinates of the point
0387:             */
0388:            public Point3d getPointCoordinatesVW() {
0389:                return pointCoordinatesVW;
0390:            }
0391:
0392:            /** 
0393:              Get the distance from the PickShape start point to the intersection point
0394:              @return the distance to the intersection point, if available.
0395:             */
0396:            public double getDistance() {
0397:                return distance;
0398:            }
0399:
0400:            /** 
0401:              Set the distance to intersection point 
0402:              @param dist the distance to the intersection point
0403:             */
0404:            void setDistance(double dist) {
0405:                distance = dist;
0406:            }
0407:
0408:            /** Set VWorld coordinates of the picked primtive
0409:              @param coords
0410:             */
0411:            void setPrimitiveCoordinatesVW(Point3d[] coords) {
0412:                primitiveCoordinatesVW = new Point3d[coords.length];
0413:                System.arraycopy(coords, 0, primitiveCoordinatesVW, 0,
0414:                        coords.length);
0415:            }
0416:
0417:            /** 
0418:              Get VWorld coordinates of the intersected primitive 
0419:              @return an array of Point3d's for the primitive that was picked
0420:             */
0421:            public Point3d[] getPrimitiveCoordinatesVW() {
0422:                return primitiveCoordinatesVW;
0423:            }
0424:
0425:            /** Set vertex indices of primitive's vertices 
0426:              @param verts array of coordinate indices
0427:             */
0428:            void setVertexIndices(int[] verts) {
0429:                primitiveVertexIndices = new int[verts.length];
0430:                System.arraycopy(verts, 0, primitiveVertexIndices, 0,
0431:                        verts.length);
0432:            }
0433:
0434:            /** 
0435:              Get vertex indices of the intersected primitive
0436:              @return an array which contains the list of indices
0437:             */
0438:            public int[] getPrimitiveVertexIndices() {
0439:                return primitiveVertexIndices;
0440:            }
0441:
0442:            /**
0443:              Returns the index of the intersected GeometryArray into the geometry
0444:              arrays in the PickResult
0445:             */
0446:            public int getGeometryArrayIndex() {
0447:                return geomIndex;
0448:            }
0449:
0450:            /* ================================================================== */
0451:            /*           Derived Data: GeometryArray				*/
0452:            /* ================================================================== */
0453:
0454:            /** Returns the GeometryArray for the intersection */
0455:            public GeometryArray getGeometryArray() {
0456:                if (geom == null) {
0457:                    GeometryArray[] ga = pickResult.getGeometryArrays();
0458:                    geom = ga[geomIndex];
0459:                    if (geom instanceof  IndexedGeometryArray) {
0460:                        iGeom = (IndexedGeometryArray) geom;
0461:                    }
0462:                    int vertexFormat = geom.getVertexFormat();
0463:                    hasColors = (0 != (vertexFormat & (GeometryArray.COLOR_3 | GeometryArray.COLOR_4)));
0464:                    hasNormals = (0 != (vertexFormat & GeometryArray.NORMALS));
0465:                    hasTexCoords = (0 != (vertexFormat & (GeometryArray.TEXTURE_COORDINATE_2 | GeometryArray.TEXTURE_COORDINATE_3)));
0466:                }
0467:                return geom;
0468:            }
0469:
0470:            /** Returns true if the geometry is indexed */
0471:            public boolean geometryIsIndexed() {
0472:                GeometryArray ga = getGeometryArray();
0473:                if (iGeom != null) {
0474:                    return true;
0475:                } else {
0476:                    return false;
0477:                }
0478:            }
0479:
0480:            /* ================================================================== */
0481:            /*           Derived Data: Closest Vertex                             */
0482:            /* ================================================================== */
0483:
0484:            /** Get coordinates of closest vertex (local) 
0485:              @return the coordinates of the vertex closest to the intersection point
0486:             */
0487:            public Point3d getClosestVertexCoordinates() {
0488:                // System.out.println("closestVertexCoordinates " + closestVertexCoordinates);
0489:                if (closestVertexCoordinates == null) {
0490:                    int vertexIndex = getClosestVertexIndex();
0491:                    int vformat = geom.getVertexFormat();
0492:                    int val;
0493:
0494:                    int[] indices = getPrimitiveCoordinateIndices();
0495:                    if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
0496:                        closestVertexCoordinates = new Point3d();
0497:                        geom.getCoordinate(indices[vertexIndex],
0498:                                closestVertexCoordinates);
0499:                        /* System.out.println("PickIntersection : closestVertexCoordinates " +
0500:                           closestVertexCoordinates + " vertexIndex " +
0501:                           vertexIndex);
0502:                         */
0503:                    } else {
0504:                        if ((vformat & GeometryArray.INTERLEAVED) == 0) {
0505:                            double[] doubleData = geom.getCoordRefDouble();
0506:                            // If data was set as float then ..
0507:                            if (doubleData == null) {
0508:                                float[] floatData = geom.getCoordRefFloat();
0509:                                if (floatData == null) {
0510:                                    Point3f[] p3fData = geom.getCoordRef3f();
0511:                                    if (p3fData == null) {
0512:                                        Point3d[] p3dData = geom
0513:                                                .getCoordRef3d();
0514:                                        closestVertexCoordinates = new Point3d(
0515:                                                p3dData[indices[vertexIndex]].x,
0516:                                                p3dData[indices[vertexIndex]].y,
0517:                                                p3dData[indices[vertexIndex]].z);
0518:                                    } else {
0519:                                        closestVertexCoordinates = new Point3d(
0520:                                                p3fData[indices[vertexIndex]].x,
0521:                                                p3fData[indices[vertexIndex]].y,
0522:                                                p3fData[indices[vertexIndex]].z);
0523:                                    }
0524:                                } else {
0525:                                    val = indices[vertexIndex] * 3; // for x,y,z
0526:                                    closestVertexCoordinates = new Point3d(
0527:                                            floatData[val], floatData[val + 1],
0528:                                            floatData[val + 2]);
0529:                                }
0530:                            } else {
0531:                                val = indices[vertexIndex] * 3; // for x,y,z
0532:                                closestVertexCoordinates = new Point3d(
0533:                                        doubleData[val], doubleData[val + 1],
0534:                                        doubleData[val + 2]);
0535:                            }
0536:                        } else {
0537:                            float[] floatData = geom.getInterleavedVertices();
0538:                            int offset = getInterleavedVertexOffset(geom);
0539:                            int stride = offset + 3; // for the vertices .
0540:                            val = stride * indices[vertexIndex] + offset;
0541:                            closestVertexCoordinates = new Point3d(
0542:                                    floatData[val], floatData[val + 1],
0543:                                    floatData[val + 2]);
0544:                        }
0545:                    }
0546:                }
0547:
0548:                return closestVertexCoordinates;
0549:            }
0550:
0551:            /** Get coordinates of closest vertex (world) 
0552:              @return the coordinates of the vertex closest to the intersection point
0553:             */
0554:            public Point3d getClosestVertexCoordinatesVW() {
0555:                if (closestVertexCoordinatesVW == null) {
0556:                    int vertexIndex = getClosestVertexIndex();
0557:                    Point3d[] coordinatesVW = getPrimitiveCoordinatesVW();
0558:                    closestVertexCoordinatesVW = coordinatesVW[vertexIndex];
0559:                }
0560:                return closestVertexCoordinatesVW;
0561:            }
0562:
0563:            /** Get index of closest vertex 
0564:              @return the index of the closest vertex
0565:             */
0566:            public int getClosestVertexIndex() {
0567:                if (closestVertexIndex == -1) {
0568:                    storeClosestVertex();
0569:                }
0570:                return closestVertexIndex;
0571:            }
0572:
0573:            /** Calculates and stores the closest vertex information */
0574:            void storeClosestVertex() {
0575:                if (closestVertexIndex == -1) {
0576:                    double maxDist = Double.MAX_VALUE;
0577:                    double curDist = Double.MAX_VALUE;
0578:                    int closestIndex = -1;
0579:                    /* System.out.println("primitiveCoordinatesVW.length " +
0580:                       primitiveCoordinatesVW.length);
0581:                     */
0582:                    for (int i = 0; i < primitiveCoordinatesVW.length; i++) {
0583:                        curDist = pointCoordinatesVW
0584:                                .distance(primitiveCoordinatesVW[i]);
0585:                        /* System.out.println("pointCoordinatesVW " + pointCoordinatesVW);
0586:                           System.out.println("primitiveCoordinatesVW[" + i + "] " +
0587:                           primitiveCoordinatesVW[i]);
0588:                           System.out.println("curDist " + curDist);
0589:                         */
0590:                        if (curDist < maxDist) {
0591:                            closestIndex = i;
0592:                            maxDist = curDist;
0593:                        }
0594:                    }
0595:                    closestVertexIndex = closestIndex;
0596:                }
0597:            }
0598:
0599:            /* ================================================================== */
0600:            /*           Derived Data: Primitive					*/
0601:            /* ================================================================== */
0602:
0603:            /** 
0604:              Get the coordinates indices for the intersected primitive.  For a non-indexed
0605:              primitive, this will be the same as the primitive vertex indices
0606:              @return an array indices
0607:             */
0608:            public int[] getPrimitiveCoordinateIndices() {
0609:
0610:                if (primitiveCoordinateIndices == null) {
0611:                    if (geometryIsIndexed()) {
0612:                        primitiveCoordinateIndices = new int[primitiveVertexIndices.length];
0613:                        for (int i = 0; i < primitiveVertexIndices.length; i++) {
0614:                            primitiveCoordinateIndices[i] = iGeom
0615:                                    .getCoordinateIndex(primitiveVertexIndices[i]);
0616:                        }
0617:                    } else {
0618:                        primitiveCoordinateIndices = primitiveVertexIndices;
0619:                    }
0620:                }
0621:                return primitiveCoordinateIndices;
0622:            }
0623:
0624:            /** 
0625:              Get the local coordinates intersected primitive 
0626:              @return an array of Point3d's for the primitive that was intersected
0627:             */
0628:            public Point3d[] getPrimitiveCoordinates() {
0629:                if (primitiveCoordinates == null) {
0630:                    primitiveCoordinates = new Point3d[primitiveVertexIndices.length];
0631:                    int[] indices = getPrimitiveCoordinateIndices();
0632:                    int vformat = geom.getVertexFormat();
0633:                    int val;
0634:
0635:                    // System.out.println("PickIntersection : indices.length - " + indices.length);
0636:                    if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
0637:                        for (int i = 0; i < indices.length; i++) {
0638:                            primitiveCoordinates[i] = new Point3d();
0639:                            // System.out.println("PickIntersection : indices["+i+"] = " + indices[i]);
0640:                            geom.getCoordinate(indices[i],
0641:                                    primitiveCoordinates[i]);
0642:                        }
0643:                    } else {
0644:                        if ((vformat & GeometryArray.INTERLEAVED) == 0) {
0645:                            double[] doubleData = geom.getCoordRefDouble();
0646:                            // If data was set as float then ..
0647:                            if (doubleData == null) {
0648:                                float[] floatData = geom.getCoordRefFloat();
0649:                                if (floatData == null) {
0650:                                    Point3f[] p3fData = geom.getCoordRef3f();
0651:                                    if (p3fData == null) {
0652:                                        Point3d[] p3dData = geom
0653:                                                .getCoordRef3d();
0654:                                        for (int i = 0; i < indices.length; i++) {
0655:                                            primitiveCoordinates[i] = new Point3d(
0656:                                                    p3dData[indices[i]].x,
0657:                                                    p3dData[indices[i]].y,
0658:                                                    p3dData[indices[i]].z);
0659:                                        }
0660:                                    } else {
0661:                                        for (int i = 0; i < indices.length; i++) {
0662:                                            primitiveCoordinates[i] = new Point3d(
0663:                                                    p3fData[indices[i]].x,
0664:                                                    p3fData[indices[i]].y,
0665:                                                    p3fData[indices[i]].z);
0666:                                        }
0667:                                    }
0668:
0669:                                } else {
0670:                                    for (int i = 0; i < indices.length; i++) {
0671:                                        val = indices[i] * 3;
0672:                                        primitiveCoordinates[i] = new Point3d(
0673:                                                floatData[val],
0674:                                                floatData[val + 1],
0675:                                                floatData[val + 2]);
0676:                                    }
0677:                                }
0678:                            } else {
0679:                                for (int i = 0; i < indices.length; i++) {
0680:                                    val = indices[i] * 3;
0681:                                    primitiveCoordinates[i] = new Point3d(
0682:                                            doubleData[val],
0683:                                            doubleData[val + 1],
0684:                                            doubleData[val + 2]);
0685:                                }
0686:                            }
0687:                        } else {
0688:                            float[] floatData = geom.getInterleavedVertices();
0689:                            int offset = getInterleavedVertexOffset(geom);
0690:                            int stride = offset + 3; // for the vertices .
0691:                            for (int i = 0; i < indices.length; i++) {
0692:                                val = stride * indices[i] + offset;
0693:                                primitiveCoordinates[i] = new Point3d(
0694:                                        floatData[val], floatData[val + 1],
0695:                                        floatData[val + 2]);
0696:                            }
0697:                        }
0698:                    }
0699:
0700:                }
0701:                return primitiveCoordinates;
0702:            }
0703:
0704:            int getInterleavedVertexOffset(GeometryArray geo) {
0705:                int offset = 0;
0706:                int vformat = geo.getVertexFormat();
0707:                if ((vformat & GeometryArray.COLOR_3) == GeometryArray.COLOR_3) {
0708:                    offset += 3;
0709:                } else if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
0710:                    offset += 4;
0711:                }
0712:                if ((vformat & GeometryArray.NORMALS) != 0)
0713:                    offset += 3;
0714:                if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
0715:                    offset += 2 * geo.getTexCoordSetCount();
0716:                } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
0717:                    offset += 3 * geo.getTexCoordSetCount();
0718:                }
0719:
0720:                return offset;
0721:            }
0722:
0723:            int getInterleavedStride(GeometryArray geo) {
0724:                int offset = 3; // Add 3 for vertices
0725:                int vformat = geo.getVertexFormat();
0726:                if ((vformat & GeometryArray.COLOR_3) == GeometryArray.COLOR_3) {
0727:                    offset += 3;
0728:                } else if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
0729:                    offset += 4;
0730:                }
0731:                if ((vformat & GeometryArray.NORMALS) != 0)
0732:                    offset += 3;
0733:                if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
0734:                    offset += 2 * geo.getTexCoordSetCount();
0735:                } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
0736:                    offset += 3 * geo.getTexCoordSetCount();
0737:                }
0738:
0739:                return offset;
0740:            }
0741:
0742:            int getInterleavedColorOffset(GeometryArray geo) {
0743:                int offset = 0;
0744:                int vformat = geo.getVertexFormat();
0745:                if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
0746:                    offset += 2 * geo.getTexCoordSetCount();
0747:                } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
0748:                    offset += 3 * geo.getTexCoordSetCount();
0749:                }
0750:
0751:                return offset;
0752:            }
0753:
0754:            int getInterleavedNormalOffset(GeometryArray geo) {
0755:                int offset = 0;
0756:                int vformat = geo.getVertexFormat();
0757:                if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
0758:                    offset += 2 * geo.getTexCoordSetCount();
0759:                } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
0760:                    offset += 3 * geo.getTexCoordSetCount();
0761:                }
0762:                if ((vformat & GeometryArray.COLOR_3) == GeometryArray.COLOR_3) {
0763:                    offset += 3;
0764:                } else if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
0765:                    offset += 4;
0766:                }
0767:                return offset;
0768:            }
0769:
0770:            /** 
0771:              Get the normal indices for the intersected primitive.  For a non-indexed
0772:              primitive, this will be the same as the primitive vertex indices
0773:              If the geometry array does not contain normals this will return null
0774:              @return an array indices
0775:             */
0776:            public int[] getPrimitiveNormalIndices() {
0777:                if (hasNormals && (primitiveNormalIndices == null)) {
0778:                    if (geometryIsIndexed()) {
0779:                        primitiveNormalIndices = new int[primitiveVertexIndices.length];
0780:                        for (int i = 0; i < primitiveVertexIndices.length; i++) {
0781:                            primitiveNormalIndices[i] = iGeom
0782:                                    .getNormalIndex(primitiveVertexIndices[i]);
0783:                        }
0784:                    } else {
0785:                        primitiveNormalIndices = primitiveVertexIndices;
0786:                    }
0787:                }
0788:                return primitiveNormalIndices;
0789:            }
0790:
0791:            /** 
0792:              Get the normals of the intersected primitive.  This will return null if
0793:              the primitive does not contain normals.
0794:              @return an array of Point3d's for the primitive that was intersected
0795:             */
0796:            public Vector3f[] getPrimitiveNormals() {
0797:                if (hasNormals && (primitiveNormals == null)) {
0798:                    primitiveNormals = new Vector3f[primitiveVertexIndices.length];
0799:                    int[] indices = getPrimitiveNormalIndices();
0800:                    int vformat = geom.getVertexFormat();
0801:                    int val;
0802:
0803:                    if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
0804:                        for (int i = 0; i < indices.length; i++) {
0805:                            primitiveNormals[i] = new Vector3f();
0806:                            geom.getNormal(indices[i], primitiveNormals[i]);
0807:                        }
0808:                    } else {
0809:                        if ((vformat & GeometryArray.INTERLEAVED) == 0) {
0810:                            float[] floatNormals = geom.getNormalRefFloat();
0811:                            if (floatNormals != null) {
0812:                                for (int i = 0; i < indices.length; i++) {
0813:                                    val = indices[i] * 3;
0814:                                    primitiveNormals[i] = new Vector3f(
0815:                                            floatNormals[val],
0816:                                            floatNormals[val + 1],
0817:                                            floatNormals[val + 2]);
0818:                                }
0819:                            } else {
0820:                                Vector3f[] normal3f = geom.getNormalRef3f();
0821:                                for (int i = 0; i < indices.length; i++) {
0822:                                    primitiveNormals[i] = new Vector3f(
0823:                                            normal3f[indices[i]].x,
0824:                                            normal3f[indices[i]].y,
0825:                                            normal3f[indices[i]].z);
0826:                                }
0827:                            }
0828:                        } else {
0829:                            float[] floatData = geom.getInterleavedVertices();
0830:                            int offset = getInterleavedColorOffset(geom);
0831:                            int stride = getInterleavedStride(geom);
0832:                            for (int i = 0; i < indices.length; i++) {
0833:                                val = stride * indices[i] + offset;
0834:                                primitiveNormals[i] = new Vector3f(
0835:                                        floatData[val], floatData[val + 1],
0836:                                        floatData[val + 2]);
0837:
0838:                            }
0839:                        }
0840:                    }
0841:                }
0842:                return primitiveNormals;
0843:            }
0844:
0845:            /** 
0846:              Get the color indices for the intersected primitive.  For a non-indexed
0847:              primitive, this will be the same as the primitive vertex indices
0848:              If the geometry array does not contain colors this will return null.
0849:              @return an array indices
0850:             */
0851:            public int[] getPrimitiveColorIndices() {
0852:                if (hasColors && (primitiveColorIndices == null)) {
0853:                    if (geometryIsIndexed()) {
0854:                        primitiveColorIndices = new int[primitiveVertexIndices.length];
0855:                        for (int i = 0; i < primitiveVertexIndices.length; i++) {
0856:                            primitiveColorIndices[i] = iGeom
0857:                                    .getColorIndex(primitiveVertexIndices[i]);
0858:                        }
0859:                    } else {
0860:                        primitiveColorIndices = primitiveVertexIndices;
0861:                    }
0862:                }
0863:                return primitiveColorIndices;
0864:            }
0865:
0866:            /** 
0867:              Get the colors of the intersected primitive.  This will return null if
0868:              the primitive does not contain colors.  If the geometry was defined
0869:              using GeometryArray.COLOR_3, the 'w' value of the color will be set to 1.0.
0870:              @return an array of Point3d's for the primitive that was intersected
0871:             */
0872:            public Color4f[] getPrimitiveColors() {
0873:                if (hasColors && (primitiveColors == null)) {
0874:                    primitiveColors = new Color4f[primitiveVertexIndices.length];
0875:                    int[] indices = getPrimitiveColorIndices();
0876:                    int vformat = geom.getVertexFormat();
0877:                    if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
0878:                        if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
0879:                            for (int i = 0; i < indices.length; i++) {
0880:                                primitiveColors[i] = new Color4f();
0881:                                geom.getColor(indices[i], primitiveColors[i]);
0882:                            }
0883:                        } else {
0884:                            Color3f color = new Color3f();
0885:                            for (int i = 0; i < indices.length; i++) {
0886:                                primitiveColors[i] = new Color4f();
0887:                                geom.getColor(indices[i], color);
0888:                                primitiveColors[i].x = color.x;
0889:                                primitiveColors[i].y = color.y;
0890:                                primitiveColors[i].z = color.z;
0891:                                primitiveColors[i].w = 1.0f;
0892:                            }
0893:                        }
0894:                    } else {
0895:                        if ((vformat & GeometryArray.INTERLEAVED) == 0) {
0896:                            float[] floatData = geom.getColorRefFloat();
0897:                            // If data was set as float then ..
0898:                            if (floatData == null) {
0899:                                byte[] byteData = geom.getColorRefByte();
0900:                                if (byteData == null) {
0901:                                    Color3f[] c3fData = geom.getColorRef3f();
0902:                                    if (c3fData == null) {
0903:                                        Color4f[] c4fData = geom
0904:                                                .getColorRef4f();
0905:                                        if (c4fData == null) {
0906:                                            Color3b[] c3bData = geom
0907:                                                    .getColorRef3b();
0908:                                            if (c3bData == null) {
0909:                                                Color4b[] c4bData = geom
0910:                                                        .getColorRef4b();
0911:                                                for (int i = 0; i < indices.length; i++) {
0912:                                                    primitiveColors[i] = new Color4f(
0913:                                                            c4bData[indices[i]].x,
0914:                                                            c4bData[indices[i]].y,
0915:                                                            c4bData[indices[i]].z,
0916:                                                            c4bData[indices[i]].w);
0917:
0918:                                                }
0919:                                            } else {
0920:                                                for (int i = 0; i < indices.length; i++) {
0921:                                                    primitiveColors[i] = new Color4f(
0922:                                                            c3bData[indices[i]].x,
0923:                                                            c3bData[indices[i]].y,
0924:                                                            c3bData[indices[i]].z,
0925:                                                            1.0f);
0926:
0927:                                                }
0928:                                            }
0929:                                        } else {
0930:                                            for (int i = 0; i < indices.length; i++) {
0931:                                                primitiveColors[i] = new Color4f(
0932:                                                        c4fData[indices[i]].x,
0933:                                                        c4fData[indices[i]].y,
0934:                                                        c4fData[indices[i]].z,
0935:                                                        c4fData[indices[i]].w);
0936:                                            }
0937:                                        }
0938:                                    } else {
0939:                                        for (int i = 0; i < indices.length; i++) {
0940:                                            primitiveColors[i] = new Color4f(
0941:                                                    c3fData[indices[i]].x,
0942:                                                    c3fData[indices[i]].y,
0943:                                                    c3fData[indices[i]].z, 1.0f);
0944:
0945:                                        }
0946:                                    }
0947:                                } else {
0948:                                    // Could be color3 or color4
0949:                                    int val;
0950:                                    if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
0951:                                        for (int i = 0; i < indices.length; i++) {
0952:                                            val = indices[i] << 2; // for color4f
0953:                                            primitiveColors[i] = new Color4f(
0954:                                                    byteData[val],
0955:                                                    byteData[val + 1],
0956:                                                    byteData[val + 2],
0957:                                                    byteData[val + 3]);
0958:
0959:                                        }
0960:                                    } else {
0961:                                        for (int i = 0; i < indices.length; i++) {
0962:                                            val = indices[i] * 3; // for color3f
0963:                                            primitiveColors[i] = new Color4f(
0964:                                                    byteData[val],
0965:                                                    byteData[val + 1],
0966:                                                    byteData[val + 2], 1.0f);
0967:
0968:                                        }
0969:                                    }
0970:                                }
0971:                            } else {
0972:                                // Could be color3 or color4
0973:                                int val;
0974:                                if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
0975:                                    for (int i = 0; i < indices.length; i++) {
0976:                                        val = indices[i] << 2; // for color4f
0977:                                        primitiveColors[i] = new Color4f(
0978:                                                floatData[val],
0979:                                                floatData[val + 1],
0980:                                                floatData[val + 2],
0981:                                                floatData[val + 3]);
0982:                                    }
0983:                                } else {
0984:                                    for (int i = 0; i < indices.length; i++) {
0985:                                        val = indices[i] * 3; // for color3f
0986:                                        primitiveColors[i] = new Color4f(
0987:                                                floatData[val],
0988:                                                floatData[val + 1],
0989:                                                floatData[val + 2], 1.0f);
0990:
0991:                                    }
0992:                                }
0993:                            }
0994:
0995:                        } else {
0996:                            float[] floatData = geom.getInterleavedVertices();
0997:                            int offset = getInterleavedColorOffset(geom);
0998:                            int stride = getInterleavedStride(geom);
0999:                            for (int i = 0; i < indices.length; i++) {
1000:                                int val = stride * indices[i] + offset;
1001:                                if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) {
1002:                                    primitiveColors[i] = new Color4f(
1003:                                            floatData[val], floatData[val + 1],
1004:                                            floatData[val + 2],
1005:                                            floatData[val + 3]);
1006:                                } else {
1007:                                    primitiveColors[i] = new Color4f(
1008:                                            floatData[val], floatData[val + 1],
1009:                                            floatData[val + 2], 1.0f);
1010:                                }
1011:                            }
1012:                        }
1013:                    }
1014:                }
1015:                return primitiveColors;
1016:            }
1017:
1018:            /** 
1019:              Get the texture coordinate indices for the intersected primitive at the specifed 
1020:              index in the specified texture coordinate set.  For a   non-indexed
1021:              primitive, this will be the same as the primitive vertex indices
1022:              If the geometry array does not contain texture coordinates, this will 
1023:              return null.
1024:              @return an array indices
1025:             */
1026:            public int[] getPrimitiveTexCoordIndices(int index) {
1027:                if (hasTexCoords && (primitiveTexCoordIndices == null)) {
1028:                    if (geometryIsIndexed()) {
1029:                        primitiveTexCoordIndices = new int[primitiveVertexIndices.length];
1030:                        for (int i = 0; i < primitiveVertexIndices.length; i++) {
1031:                            primitiveTexCoordIndices[i] = iGeom
1032:                                    .getTextureCoordinateIndex(index,
1033:                                            primitiveVertexIndices[i]);
1034:                        }
1035:                    } else {
1036:                        primitiveTexCoordIndices = primitiveVertexIndices;
1037:                    }
1038:                }
1039:                return primitiveTexCoordIndices;
1040:            }
1041:
1042:            /** 
1043:              Get the texture coordinates of the intersected primitive at the specifed 
1044:              index in the specified texture coordinate set.
1045:              null if the primitive does not contain texture coordinates.  
1046:              If the geometry was defined
1047:              using GeometryArray.TEXTURE_COORDINATE_2, the 'z' value of the texture
1048:              coordinate will be set to 0.0.
1049:              @return an array of TexCoord3f's for the primitive that was intersected
1050:             */
1051:            public TexCoord3f[] getPrimitiveTexCoords(int index) {
1052:                if (primitiveTexCoords == null) {
1053:                    primitiveTexCoords = new TexCoord3f[primitiveVertexIndices.length];
1054:                    TexCoord2f primitiveTexCoords2DTmp = new TexCoord2f();
1055:
1056:                    int[] indices = getPrimitiveTexCoordIndices(index);
1057:                    int vformat = geom.getVertexFormat();
1058:                    if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
1059:                        for (int i = 0; i < indices.length; i++) {
1060:                            primitiveTexCoords[i] = new TexCoord3f();
1061:                            geom.getTextureCoordinate(index, indices[i],
1062:                                    primitiveTexCoords2DTmp);
1063:                            primitiveTexCoords[i].set(
1064:                                    primitiveTexCoords2DTmp.x,
1065:                                    primitiveTexCoords2DTmp.y, 0.0f);
1066:                        }
1067:                    } else {
1068:                        if ((vformat & GeometryArray.INTERLEAVED) == 0) {
1069:                            int val;
1070:                            float[] floatTexCoords = geom
1071:                                    .getTexCoordRefFloat(index);
1072:                            if (floatTexCoords != null) {
1073:                                if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
1074:                                    for (int i = 0; i < indices.length; i++) {
1075:                                        val = indices[i] << 1; // t2f
1076:                                        primitiveTexCoords[i] = new TexCoord3f(
1077:                                                floatTexCoords[val],
1078:                                                floatTexCoords[val + 1], 0.0f);
1079:                                    }
1080:                                } else {
1081:                                    for (int i = 0; i < indices.length; i++) {
1082:                                        val = indices[i] * 3; // t3f
1083:                                        primitiveTexCoords[i] = new TexCoord3f(
1084:                                                floatTexCoords[val],
1085:                                                floatTexCoords[val + 1],
1086:                                                floatTexCoords[val + 2]);
1087:                                    }
1088:                                }
1089:                            } else {
1090:                                TexCoord2f[] texCoord2f = geom
1091:                                        .getTexCoordRef2f(index);
1092:                                if (texCoord2f != null) {
1093:                                    for (int i = 0; i < indices.length; i++) {
1094:                                        primitiveTexCoords[i] = new TexCoord3f(
1095:                                                texCoord2f[indices[i]].x,
1096:                                                texCoord2f[indices[i]].y, 0.0f);
1097:                                    }
1098:                                } else {
1099:                                    TexCoord3f[] texCoord3f = geom
1100:                                            .getTexCoordRef3f(index);
1101:                                    for (int i = 0; i < indices.length; i++) {
1102:                                        primitiveTexCoords[i] = new TexCoord3f(
1103:                                                texCoord3f[indices[i]].x,
1104:                                                texCoord3f[indices[i]].y,
1105:                                                texCoord3f[indices[i]].z);
1106:                                    }
1107:                                }
1108:
1109:                            }
1110:                        } else {
1111:                            float[] floatData = geom.getInterleavedVertices();
1112:                            int stride = getInterleavedStride(geom);
1113:                            int offset;
1114:                            // Get the correct tex coord set
1115:                            if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
1116:                                offset = index << 1;
1117:                            } else {
1118:                                offset = index * 3;
1119:                            }
1120:                            for (int i = 0; i < indices.length; i++) {
1121:                                int val = stride * indices[i];
1122:                                if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
1123:                                    primitiveTexCoords[i] = new TexCoord3f(
1124:                                            floatData[val + offset],
1125:                                            floatData[val + 1 + offset], 0.0f);
1126:                                } else {
1127:                                    primitiveTexCoords[i] = new TexCoord3f(
1128:                                            floatData[val + offset],
1129:                                            floatData[val + 1 + offset],
1130:                                            floatData[val + 2 + offset]);
1131:                                }
1132:                            }
1133:                        }
1134:                    }
1135:                }
1136:                return primitiveTexCoords;
1137:            }
1138:
1139:            /* ================================================================== */
1140:            /*           Derived Data: Intersection Point				*/
1141:            /* ================================================================== */
1142:
1143:            /**
1144:              Returns the coordinates of the intersection point (local coordinates),
1145:              if available.
1146:              @return coordinates of the intersection point
1147:             */
1148:            public Point3d getPointCoordinates() {
1149:                if (pointCoordinates == null) {
1150:                    double[] weights = getInterpWeights();
1151:                    Point3d[] coords = getPrimitiveCoordinates();
1152:                    pointCoordinates = new Point3d();
1153:                    for (int i = 0; i < weights.length; i++) {
1154:                        pointCoordinates.x += weights[i] * coords[i].x;
1155:                        pointCoordinates.y += weights[i] * coords[i].y;
1156:                        pointCoordinates.z += weights[i] * coords[i].z;
1157:                    }
1158:                }
1159:                return pointCoordinates;
1160:            }
1161:
1162:            /**
1163:              Returns the normal of the intersection point. Returns null if the geometry
1164:              does not contain normals.
1165:              @return normal at the intersection point.  
1166:             */
1167:            public Vector3f getPointNormal() {
1168:                if (hasNormals && (pointNormal == null)) {
1169:                    double[] weights = getInterpWeights();
1170:                    Vector3f[] normals = getPrimitiveNormals();
1171:                    pointNormal = new Vector3f();
1172:                    for (int i = 0; i < weights.length; i++) {
1173:                        pointNormal.x += (float) weights[i] * normals[i].x;
1174:                        pointNormal.y += (float) weights[i] * normals[i].y;
1175:                        pointNormal.z += (float) weights[i] * normals[i].z;
1176:                    }
1177:                }
1178:                return pointNormal;
1179:            }
1180:
1181:            /**
1182:              Returns the color of the intersection point. Returns null if the geometry
1183:              does not contain colors.  If the geometry was defined with
1184:              GeometryArray.COLOR_3, the 'w' component of the color will initialized to 
1185:              1.0
1186:              @return color at the intersection point.  
1187:             */
1188:            public Color4f getPointColor() {
1189:                if (hasColors && (pointColor == null)) {
1190:                    double[] weights = getInterpWeights();
1191:                    Color4f[] colors = getPrimitiveColors();
1192:                    pointColor = new Color4f();
1193:                    for (int i = 0; i < weights.length; i++) {
1194:                        pointColor.x += (float) weights[i] * colors[i].x;
1195:                        pointColor.y += (float) weights[i] * colors[i].y;
1196:                        pointColor.z += (float) weights[i] * colors[i].z;
1197:                        pointColor.w += (float) weights[i] * colors[i].w;
1198:                    }
1199:                }
1200:                return pointColor;
1201:            }
1202:
1203:            /**
1204:              Returns the texture coordinate of the intersection point at the specifed 
1205:              index in the specified texture coordinate set.
1206:              Returns null if the geometry
1207:              does not contain texture coordinates.  If the geometry was defined with
1208:              GeometryArray.TEXTURE_COORDINATE_3, the 'z' component of the texture
1209:              coordinate will initialized to 0.0
1210:              @return texture coordinate at the intersection point.  
1211:             */
1212:            public TexCoord3f getPointTextureCoordinate(int index) {
1213:                if (hasTexCoords && (pointTexCoord == null)) {
1214:                    double[] weights = getInterpWeights();
1215:                    TexCoord3f[] texCoords = getPrimitiveTexCoords(index);
1216:                    pointTexCoord = new TexCoord3f();
1217:                    for (int i = 0; i < weights.length; i++) {
1218:                        pointTexCoord.x += (float) weights[i] * texCoords[i].x;
1219:                        pointTexCoord.y += (float) weights[i] * texCoords[i].y;
1220:                        pointTexCoord.z += (float) weights[i] * texCoords[i].z;
1221:                    }
1222:                }
1223:                return pointTexCoord;
1224:            }
1225:
1226:            /* ================================================================== */
1227:            /*      Utility code for interpolating intersection point data        */
1228:            /* ================================================================== */
1229:
1230:            /* absolute value */
1231:            double abs(double value) {
1232:                if (value < 0.0) {
1233:                    return -value;
1234:                } else {
1235:                    return value;
1236:                }
1237:            }
1238:
1239:            /* return the axis corresponding to the largest component of delta */
1240:            int maxAxis(Vector3d delta) {
1241:                int axis = X_AXIS;
1242:                double max = abs(delta.x);
1243:                if (abs(delta.y) > max) {
1244:                    axis = Y_AXIS;
1245:                    max = abs(delta.y);
1246:                }
1247:                if (abs(delta.z) > max) {
1248:                    axis = Z_AXIS;
1249:                }
1250:                return axis;
1251:            }
1252:
1253:            /* Triangle interpolation. Basic idea:  
1254:             * Map the verticies of the triangle to the form:
1255:             *
1256:             * L--------R
1257:             *  \      /
1258:             * IL+--P-+IR
1259:             *    \  /
1260:             *    Base
1261:             *
1262:               where P is the intersection point Base, L and R and the triangle
1263:               points.  IL and IR are the projections if P along the Base-L and Base-R
1264:               edges using an axis:
1265:
1266:               IL =  leftFactor * L + (1- leftFactor) * Base
1267:               IR = rightFactor * R + (1-rightFactor) * Base
1268:
1269:               then find the interp factor, midFactor, for P between IL and IR.  If 
1270:               this is outside the range 0->1 then we have the wrong triangle of a 
1271:               quad and we return false.  
1272:            
1273:               Else, the weighting is:
1274:
1275:               IP = midFactor * IL + (1 - midFactor) * IR;
1276:
1277:               Solving for weights for the formula:
1278:               IP = BaseWeight * Base + LeftWeight * L + RightWeight * R;
1279:               We get:
1280:               BaseWeight = 1 - midFactor * leftFactor 
1281:               - rightFactor + midFactor * rightFactor;
1282:               LeftWeight = midFactor * leftFactor;
1283:               RightWeight = righFactor - midFactor * rightFactor;
1284:               As a check, note that the sum of the weights is 1.0.
1285:             */
1286:
1287:            boolean interpTriangle(int index0, int index1, int index2,
1288:                    Point3d[] coords, Point3d intPt) {
1289:
1290:                // find the longest edge, we'll use that to pick the axis */
1291:                Vector3d delta0 = new Vector3d();
1292:                Vector3d delta1 = new Vector3d();
1293:                Vector3d delta2 = new Vector3d();
1294:                delta0.sub(coords[index1], coords[index0]);
1295:                delta1.sub(coords[index2], coords[index0]);
1296:                delta2.sub(coords[index2], coords[index1]);
1297:                double len0 = delta0.lengthSquared();
1298:                double len1 = delta1.lengthSquared();
1299:                double len2 = delta2.lengthSquared();
1300:                Vector3d longest = delta0;
1301:                double maxLen = len0;
1302:                if (len1 > maxLen) {
1303:                    longest = delta1;
1304:                    maxLen = len1;
1305:                }
1306:                if (len2 > maxLen) {
1307:                    longest = delta2;
1308:                }
1309:                int mainAxis = maxAxis(longest);
1310:
1311:                /*
1312:                  System.out.println("index0 = " + index0 + " index1 = " + index1 +
1313:                  " index2 = " + index2);
1314:                  
1315:                  System.out.println("coords[index0] = " + coords[index0]);
1316:                  System.out.println("coords[index1] = " + coords[index1]);
1317:                  System.out.println("coords[index2] = " + coords[index2]);
1318:                  System.out.println("intPt = " + intPt);
1319:                  
1320:                  System.out.println("delta0 = " + delta0 + " len0 " + len0);
1321:                  System.out.println("delta1 = " + delta1 + " len1 " + len1);
1322:                  System.out.println("delta2 = " + delta2 + " len2 " + len2);
1323:                 */
1324:
1325:                /* now project the intersection point along the axis onto the edges */
1326:                double[] factor = new double[3];
1327:                /* the factor is for the projection opposide the vertex 0 = 1->2, etc*/
1328:                factor[0] = getInterpFactorForBase(intPt, coords[index1],
1329:                        coords[index2], mainAxis);
1330:                factor[1] = getInterpFactorForBase(intPt, coords[index2],
1331:                        coords[index0], mainAxis);
1332:                factor[2] = getInterpFactorForBase(intPt, coords[index0],
1333:                        coords[index1], mainAxis);
1334:
1335:                if (debug) {
1336:                    System.out.println("intPt  = " + intPt);
1337:                    switch (mainAxis) {
1338:                    case X_AXIS:
1339:                        System.out.println("mainAxis = X_AXIS");
1340:                        break;
1341:                    case Y_AXIS:
1342:                        System.out.println("mainAxis = Y_AXIS");
1343:                        break;
1344:                    case Z_AXIS:
1345:                        System.out.println("mainAxis = Z_AXIS");
1346:                        break;
1347:                    }
1348:                    System.out.println("factor[0] =  " + factor[0]);
1349:                    System.out.println("factor[1] =  " + factor[1]);
1350:                    System.out.println("factor[2] =  " + factor[2]);
1351:                }
1352:
1353:                /* Find the factor that is out of range, it will tell us which
1354:                 * vertex to use for base
1355:                 */
1356:                int base, left, right;
1357:                double leftFactor, rightFactor;
1358:                if ((factor[0] < 0.0) || (factor[0] > 1.0)) {
1359:                    base = index0;
1360:                    right = index1;
1361:                    left = index2;
1362:                    rightFactor = factor[2];
1363:                    leftFactor = 1.0 - factor[1];
1364:                    if (debug) {
1365:                        System.out.println("base 0, rightFactor = "
1366:                                + rightFactor + " leftFactor = " + leftFactor);
1367:                    }
1368:                } else if ((factor[1] < 0.0) || (factor[1] > 1.0)) {
1369:                    base = index1;
1370:                    right = index2;
1371:                    left = index0;
1372:                    rightFactor = factor[0];
1373:                    leftFactor = 1.0 - factor[2];
1374:                    if (debug) {
1375:                        System.out.println("base 1, rightFactor = "
1376:                                + rightFactor + " leftFactor = " + leftFactor);
1377:                    }
1378:                } else {
1379:                    base = index2;
1380:                    right = index0;
1381:                    left = index1;
1382:                    rightFactor = factor[1];
1383:                    leftFactor = 1.0 - factor[0];
1384:                    if (debug) {
1385:                        System.out.println("base 2, rightFactor = "
1386:                                + rightFactor + " leftFactor = " + leftFactor);
1387:                    }
1388:                }
1389:                if (debug) {
1390:                    System.out.println("base  = " + coords[base]);
1391:                    System.out.println("left  = " + coords[left]);
1392:                    System.out.println("right = " + coords[right]);
1393:                }
1394:                /* find iLeft and iRight */
1395:                Point3d iLeft = new Point3d(leftFactor * coords[left].x
1396:                        + (1.0 - leftFactor) * coords[base].x, leftFactor
1397:                        * coords[left].y + (1.0 - leftFactor) * coords[base].y,
1398:                        leftFactor * coords[left].z + (1.0 - leftFactor)
1399:                                * coords[base].z);
1400:
1401:                Point3d iRight = new Point3d(rightFactor * coords[right].x
1402:                        + (1.0 - rightFactor) * coords[base].x, rightFactor
1403:                        * coords[right].y + (1.0 - rightFactor)
1404:                        * coords[base].y, rightFactor * coords[right].z
1405:                        + (1.0 - rightFactor) * coords[base].z);
1406:
1407:                if (debug) {
1408:                    System.out.println("iLeft  = " + iLeft);
1409:                    System.out.println("iRight  = " + iRight);
1410:                }
1411:
1412:                /* now find an axis and solve for midFactor */
1413:                delta0.sub(iLeft, iRight);
1414:                int midAxis = maxAxis(delta0);
1415:                double midFactor = getInterpFactor(intPt, iRight, iLeft,
1416:                        midAxis);
1417:
1418:                if (debug) {
1419:                    switch (midAxis) {
1420:                    case X_AXIS:
1421:                        System.out.println("midAxis = X_AXIS");
1422:                        break;
1423:                    case Y_AXIS:
1424:                        System.out.println("midAxis = Y_AXIS");
1425:                        break;
1426:                    case Z_AXIS:
1427:                        System.out.println("midAxis = Z_AXIS");
1428:                        break;
1429:                    }
1430:                    System.out.println("midFactor = " + midFactor);
1431:                }
1432:
1433:                if (midFactor < 0.0) {
1434:                    // System.out.println("midFactor = " + midFactor);
1435:                    if ((midFactor + TOL) >= 0.0) {
1436:                        // System.out.println("In Tol case : midFactor = " + midFactor);
1437:                        midFactor = 0.0;
1438:                    } else {
1439:                        /* int point is outside triangle */
1440:                        return false;
1441:                    }
1442:                } else if (midFactor > 1.0) {
1443:                    // System.out.println("midFactor = " + midFactor);
1444:                    if ((midFactor - TOL) <= 1.0) {
1445:                        // System.out.println("In Tol case : midFactor = " + midFactor);
1446:                        midFactor = 1.0;
1447:                    } else {
1448:                        /* int point is outside triangle */
1449:                        return false;
1450:                    }
1451:                }
1452:
1453:                // Assign the weights
1454:                interpWeights[base] = 1.0 - midFactor * leftFactor
1455:                        - rightFactor + midFactor * rightFactor;
1456:                interpWeights[left] = midFactor * leftFactor;
1457:                interpWeights[right] = rightFactor - midFactor * rightFactor;
1458:                return true;
1459:
1460:            }
1461:
1462:            /* Get the interpolation weights for each of the verticies of the 
1463:             * primitive.
1464:             */
1465:            double[] getInterpWeights() {
1466:
1467:                Point3d pt = getPointCoordinatesVW();
1468:                Point3d[] coordinates = getPrimitiveCoordinatesVW();
1469:                double factor;
1470:                int axis;
1471:
1472:                if (interpWeights != null) {
1473:                    return interpWeights;
1474:                }
1475:
1476:                interpWeights = new double[coordinates.length];
1477:
1478:                // Interpolate
1479:                switch (coordinates.length) {
1480:                case 1:
1481:                    // Nothing to interpolate
1482:                    interpWeights[0] = 1.0;
1483:                    break;
1484:                case 2: // edge
1485:                    Vector3d delta = new Vector3d();
1486:                    delta.sub(coordinates[1], coordinates[0]);
1487:                    axis = maxAxis(delta);
1488:                    factor = getInterpFactor(pt, coordinates[1],
1489:                            coordinates[0], axis);
1490:                    interpWeights[0] = factor;
1491:                    interpWeights[1] = 1.0 - factor;
1492:                    break;
1493:                case 3: // triangle
1494:                    if (!interpTriangle(0, 1, 2, coordinates, pt)) {
1495:                        throw new RuntimeException(
1496:                                "Interp point outside triangle");
1497:                    }
1498:                    break;
1499:                case 4: // quad
1500:                    if (!interpTriangle(0, 1, 2, coordinates, pt)) {
1501:                        if (!interpTriangle(0, 2, 3, coordinates, pt)) {
1502:                            throw new RuntimeException(
1503:                                    "Interp point outside quad");
1504:                        }
1505:                    }
1506:                    break;
1507:                default:
1508:                    throw new RuntimeException("Unexpected number of points.");
1509:                }
1510:                return interpWeights;
1511:            }
1512:
1513:            /** 
1514:              Calculate the interpolation factor for point p by projecting it along
1515:              an axis (x,y,z) onto the edge between p1 and p2.  If the result is 
1516:              in the 0->1 range, point is between p1 and p2 (0 = point is at p1, 
1517:              1 => point is at p2).
1518:             */
1519:            private static float getInterpFactor(Point3d p, Point3d p1,
1520:                    Point3d p2, int axis) {
1521:                float t;
1522:                switch (axis) {
1523:                case X_AXIS:
1524:                    if (p1.x == p2.x)
1525:                        //t = Float.MAX_VALUE; // TODO: should be 0?
1526:                        t = 0.0f;
1527:                    else
1528:                        t = (float) ((p1.x - p.x) / (p1.x - p2.x));
1529:                    break;
1530:                case Y_AXIS:
1531:                    if (p1.y == p2.y)
1532:                        // t = Float.MAX_VALUE;
1533:                        t = 0.0f;
1534:                    else
1535:                        t = (float) ((p1.y - p.y) / (p1.y - p2.y));
1536:                    break;
1537:                case Z_AXIS:
1538:                    if (p1.z == p2.z)
1539:                        // t = Float.MAX_VALUE;
1540:                        t = 0.0f;
1541:                    else
1542:                        t = (float) ((p1.z - p.z) / (p1.z - p2.z));
1543:                    break;
1544:                default:
1545:                    throw new RuntimeException("invalid axis parameter " + axis
1546:                            + " (must be 0-2)");
1547:                }
1548:                return t;
1549:            }
1550:
1551:            /** 
1552:              Calculate the interpolation factor for point p by projecting it along
1553:              an axis (x,y,z) onto the edge between p1 and p2.  If the result is 
1554:              in the 0->1 range, point is between p1 and p2 (0 = point is at p1, 
1555:              1 => point is at p2).
1556:              return MAX_VALUE if component of vertices are the same.
1557:             */
1558:            private static float getInterpFactorForBase(Point3d p, Point3d p1,
1559:                    Point3d p2, int axis) {
1560:                float t;
1561:                switch (axis) {
1562:                case X_AXIS:
1563:                    if (p1.x == p2.x)
1564:                        t = Float.MAX_VALUE;
1565:                    else
1566:                        t = (float) ((p1.x - p.x) / (p1.x - p2.x));
1567:                    break;
1568:                case Y_AXIS:
1569:                    if (p1.y == p2.y)
1570:                        t = Float.MAX_VALUE;
1571:                    else
1572:                        t = (float) ((p1.y - p.y) / (p1.y - p2.y));
1573:                    break;
1574:                case Z_AXIS:
1575:                    if (p1.z == p2.z)
1576:                        t = Float.MAX_VALUE;
1577:                    else
1578:                        t = (float) ((p1.z - p.z) / (p1.z - p2.z));
1579:                    break;
1580:                default:
1581:                    throw new RuntimeException("invalid axis parameter " + axis
1582:                            + " (must be 0-2)");
1583:                }
1584:                return t;
1585:            }
1586:
1587:        } // PickIntersection
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.