📄 pickintersection.java
字号:
/* * $RCSfile: PickIntersection.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. * * $Revision: 1.5 $ * $Date: 2007/02/09 17:20:24 $ * $State: Exp $ */package com.sun.j3d.utils.pickfast;import javax.vecmath.*;import javax.media.j3d.*;import com.sun.j3d.utils.geometry.Primitive;/** * Holds information about an intersection of a PickShape with a Node * as part of a PickInfo.IntersectionInfo. Information about * the intersected geometry, intersected primitive, intersection point, and * closest vertex can be inquired. * <p> * The intersected primitive indicates which primitive out of the GeometryArray * was intersected (where the primitive is a point, line, triangle or quad, * not a * <code>com.sun.j3d.utils.geometry.Primitive)</code>. * For example, the intersection would indicate which triangle out of a * triangle strip was intersected. * The methods which return primitive data will have one value if the primitive * is * a point, two values if the primitive is a line, three values if the primitive * is a triangle and four values if the primitive is quad. * <p> * The primitive's VWorld coordinates are saved when then intersection is * calculated. The local coordinates, normal, color and texture coordinates * for the primitive can also be inquired if they are present and readable. * <p> * The intersection point is the location on the primitive which intersects the * pick shape closest to the center of the pick shape. The intersection point's * location in VWorld coordinates is saved when the intersection is calculated. * The local coordinates, normal, color and texture coordiantes of at the * intersection can be interpolated if they are present and readable. * <p> * The closest vertex is the vertex of the primitive closest to the intersection * point. The vertex index, VWorld coordinates and local coordinates of the * closest vertex can be inquired. The normal, color and texture coordinate * of the closest vertex can be inquired from the geometry array: * <p><blockquote><pre> * Vector3f getNormal(PickIntersection pi, int vertexIndex) { * int index; * Vector3d normal = new Vector3f(); * GeometryArray ga = pickIntersection.getGeometryArray(); * if (pickIntersection.geometryIsIndexed()) { * index = ga.getNormalIndex(vertexIndex); * } else { * index = vertexIndex; * } * ga.getNormal(index, normal); * return normal; * } * </pre></blockquote> * <p> * The color, normal * and texture coordinate information for the intersected primitive and the * intersection point * can be inquired * the geometry includes them and the corresponding READ capibility bits are * set. */public class PickIntersection { /* The intersection point */ // Point3d getIntersectionPoint() /* Distance between start point of pickShape and intersection point */ // double getDistance() /* The vertex indices of the intersected primitive in the geometry */ // int[] getVertexIndices() /*************************/ /** Weight factors for interpolation, values correspond to vertex indices, * sum == 1 */ private double[] interpWeights; private static final boolean debug = false; // Axis constants private static final int X_AXIS = 1; private static final int Y_AXIS = 2; private static final int Z_AXIS = 3; // Tolerance for numerical stability static final double TOL = 1.0e-5; /* The references to the intersectionInfo object */ private PickInfo.IntersectionInfo iInfo = null; private Transform3D l2vw = null; private Geometry geometry = null; private boolean geometryIsIndexed = false; private double distance; private boolean hasColors; private boolean hasNormals; private boolean hasTexCoords; // Primitive /* indices for the different data types */ private int[] primitiveCoordinateIndices; private int[] primitiveNormalIndices; private int[] primitiveColorIndices; private int[] primitiveTexCoordIndices; /** Indices of the intersected primitive */ private int[] primitiveVertexIndices = null; /* Local coordinates of the intersected primitive */ private Point3d[] primitiveCoordinates = null; /** VWorld coordinates of intersected primitive */ private Point3d[] primitiveCoordinatesVW = null; /* Normals of the intersected primitive */ private Vector3f[] primitiveNormals = null; /* Colors of the intersected primitive */ private Color4f[] primitiveColors = null; /* TextureCoordinates of the intersected primitive */ private TexCoord3f[] primitiveTexCoords = null; // Intersection point /** VWorld Coordinates of the intersection point */ private Point3d pointCoordinatesVW = null; /** Local Coordinates of the intersection point */ private Point3d pointCoordinates = null; /** Normal at the intersection point */ private Vector3f pointNormal = null; /** Color at the intersection point */ private Color4f pointColor = null; /** TexCoord at the intersection point */ private TexCoord3f pointTexCoord = null; // Closest Vertex /** Index of the closest vertex */ private int closestVertexIndex = -1; /** Coordinates of the closest vertex */ private Point3d closestVertexCoordinates = null; /** Coordinates of the closest vertex (World coordinates) */ private Point3d closestVertexCoordinatesVW = null; /* =================== METHODS ======================= */ /** * Constructor * @param intersectionInfo The IntersectionInfo this intersection is part of. */ public PickIntersection (Transform3D localToVWorld, PickInfo.IntersectionInfo intersectionInfo) { // Should check and throw NPE if the following is null. // localToVWorld can't be null. l2vw = localToVWorld; // intersectionInfo can't be null. iInfo = intersectionInfo; // geometry can't be null. geometry = iInfo.getGeometry(); pointCoordinates = iInfo.getIntersectionPoint(); distance = iInfo.getDistance(); primitiveVertexIndices = iInfo.getVertexIndices(); if (geometry instanceof GeometryArray) { int vertexFormat = ((GeometryArray)geometry).getVertexFormat(); hasColors = (0 != (vertexFormat & (GeometryArray.COLOR_3 | GeometryArray.COLOR_4))); hasNormals = (0 != (vertexFormat & GeometryArray.NORMALS)); hasTexCoords = (0 != (vertexFormat & (GeometryArray.TEXTURE_COORDINATE_2 | GeometryArray.TEXTURE_COORDINATE_3))); if (geometry instanceof IndexedGeometryArray) { geometryIsIndexed = true; } } } /** * Returns true if the geometry is indexed * */ public boolean geometryIsIndexed() { return geometryIsIndexed; } /** * Get coordinates of closest vertex (local) * @return the coordinates of the vertex closest to the intersection point * */ public Point3d getClosestVertexCoordinates() { // System.out.println("PI.closestVertexCoordinates " + closestVertexCoordinates); GeometryArray geom = (GeometryArray) geometry; if (closestVertexCoordinates == null) { int vertexIndex = getClosestVertexIndex(); int vformat = geom.getVertexFormat(); int val; int[] indices = getPrimitiveCoordinateIndices(); if ((vformat & GeometryArray.BY_REFERENCE) == 0) { closestVertexCoordinates = new Point3d(); geom.getCoordinate(indices[vertexIndex], closestVertexCoordinates); // System.out.println("PI.closestVertexCoordinates " +// closestVertexCoordinates + " vertexIndex " +// vertexIndex); } else { if ((vformat & GeometryArray.INTERLEAVED) == 0) { double[] doubleData = geom.getCoordRefDouble(); // If data was set as float then .. if (doubleData == null) { float[] floatData = geom.getCoordRefFloat(); if (floatData == null) { throw new UnsupportedOperationException("Deprecated : BY_REF - p3f and p3d"); } else { val = indices[vertexIndex] * 3; // for x,y,z closestVertexCoordinates = new Point3d(floatData[val], floatData[val+1], floatData[val+2]); } } else { val = indices[vertexIndex] * 3; // for x,y,z closestVertexCoordinates = new Point3d(doubleData[val], doubleData[val+1], doubleData[val+2]); } } else { float[] floatData = geom.getInterleavedVertices(); int offset = getInterleavedVertexOffset(geom); int stride = offset + 3; // for the vertices . val = stride * indices[vertexIndex]+offset; closestVertexCoordinates = new Point3d(floatData[val], floatData[val+1], floatData[val+2]); } } } return closestVertexCoordinates; } /** * Get coordinates of closest vertex (world) * @return the coordinates of the vertex closest to the intersection point * */ public Point3d getClosestVertexCoordinatesVW() { if (closestVertexCoordinatesVW == null) { int vertexIndex = getClosestVertexIndex(); Point3d[] coordinatesVW = getPrimitiveCoordinatesVW(); closestVertexCoordinatesVW = coordinatesVW[vertexIndex]; } return closestVertexCoordinatesVW; } /** * Get index of closest vertex * @return the index of the closest vertex */ public int getClosestVertexIndex() { if (closestVertexIndex == -1) { double maxDist = Double.MAX_VALUE; double curDist = Double.MAX_VALUE; int closestIndex = -1; primitiveCoordinates = getPrimitiveCoordinates(); assert(primitiveCoordinates != null);// System.out.println("PI.getClosestVertexIndex : primitiveCoordinates.length " +// primitiveCoordinates.length); for (int i=0;i<primitiveCoordinates.length;i++) { curDist = pointCoordinates.distance (primitiveCoordinates[i]); // System.out.println("pointCoordinates " + pointCoordinates);// System.out.println("primitiveCoordinates[" + i + "] " +// primitiveCoordinates[i]);// System.out.println("curDist " + curDist); if (curDist < maxDist) { closestIndex = i; maxDist = curDist; } } closestVertexIndex = closestIndex; } return closestVertexIndex; } /** * Get the distance from the PickShape start point to the intersection point * @return the distance to the intersection point, if available. */ public double getDistance() { return distance; } /** * Returns the color of the intersection point. Returns null if the geometry * does not contain colors. If the geometry was defined with * GeometryArray.COLOR_3, the 'w' component of the color will initialized to * 1.0 * @return color at the intersection point. */ public Color4f getPointColor() { if (hasColors && (pointColor == null)) { double[] weights = getInterpWeights(); Color4f[] colors = getPrimitiveColors(); pointColor = new Color4f(); for (int i = 0; i < weights.length; i++) { pointColor.x += (float) weights[i] * colors[i].x; pointColor.y += (float) weights[i] * colors[i].y; pointColor.z += (float) weights[i] * colors[i].z; pointColor.w += (float) weights[i] * colors[i].w; } } return pointColor; } /** * Returns the coordinates of the intersection point (local coordinates), * if available. * @return coordinates of the intersection point */ public Point3d getPointCoordinates() { return pointCoordinates; } /** * Returns the coordinates of the intersection point (world coordinates), * if available. * @return coordinates of the point */ public Point3d getPointCoordinatesVW() { if (pointCoordinatesVW != null) { return pointCoordinatesVW; } pointCoordinatesVW = new Point3d(); pointCoordinatesVW.x = pointCoordinates.x; pointCoordinatesVW.y = pointCoordinates.y; pointCoordinatesVW.z = pointCoordinates.z; l2vw.transform(pointCoordinatesVW); return pointCoordinatesVW; } /** * Returns the normal of the intersection point. Returns null if the geometry * does not contain normals. * @return normal at the intersection point. */ public Vector3f getPointNormal() { if (hasNormals && (pointNormal == null)) { double[] weights = getInterpWeights(); Vector3f[] normals = getPrimitiveNormals(); pointNormal = new Vector3f(); for (int i = 0; i < weights.length; i++) { pointNormal.x += (float) weights[i] * normals[i].x; pointNormal.y += (float) weights[i] * normals[i].y; pointNormal.z += (float) weights[i] * normals[i].z; } } return pointNormal; } /** * Returns the texture coordinate of the intersection point at the specifed * index in the specified texture coordinate set. * Returns null if the geometry * does not contain texture coordinates. If the geometry was defined with * GeometryArray.TEXTURE_COORDINATE_3, the 'z' component of the texture * coordinate will initialized to 0.0 * @return texture coordinate at the intersection point. */ public TexCoord3f getPointTextureCoordinate(int index) { if (hasTexCoords && (pointTexCoord == null)) { double[] weights = getInterpWeights(); TexCoord3f[] texCoords = getPrimitiveTexCoords(index); pointTexCoord = new TexCoord3f(); for (int i = 0; i < weights.length; i++) { pointTexCoord.x += (float) weights[i] * texCoords[i].x; pointTexCoord.y += (float) weights[i] * texCoords[i].y; pointTexCoord.z += (float) weights[i] * texCoords[i].z; } } return pointTexCoord; } /** * Get the color indices for the intersected primitive. For a non-indexed * primitive, this will be the same as the primitive vertex indices * If the geometry array does not contain colors this will return null. * @return an array indices */ public int[] getPrimitiveColorIndices() { if (hasColors && (primitiveColorIndices == null)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -