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