summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChien Yang <[email protected]>2005-11-03 22:43:47 +0000
committerChien Yang <[email protected]>2005-11-03 22:43:47 +0000
commitc7cfa6143c8bf20068cfbd58b59122b3143c45c9 (patch)
tree6c4b24c084c2d2ee5973bda27d22bd4f8659e9b4
parentfa2bb8e89d549471f52b53acebd83f75c10c6aaa (diff)
Implemented PickIntersection class
git-svn-id: https://svn.java.net/svn/j3d-core-utils~svn/trunk@85 9497e636-51bd-65ba-982d-a4982e1767a5
-rw-r--r--src/classes/share/com/sun/j3d/utils/pickfast/PickIntersection.java1396
1 files changed, 1179 insertions, 217 deletions
diff --git a/src/classes/share/com/sun/j3d/utils/pickfast/PickIntersection.java b/src/classes/share/com/sun/j3d/utils/pickfast/PickIntersection.java
index 6403f89..5987ca8 100644
--- a/src/classes/share/com/sun/j3d/utils/pickfast/PickIntersection.java
+++ b/src/classes/share/com/sun/j3d/utils/pickfast/PickIntersection.java
@@ -105,313 +105,1275 @@ import com.sun.j3d.utils.geometry.Primitive;
public class PickIntersection {
- /* =================== METHODS ======================= */
-
- /** Constructor
- @param intersectionInfo The IntersectionInfo this intersection is part of.
- */
- //PickIntersection (PickResult pr, GeometryArray geomArr) {
- public PickIntersection (PickInfo.IntersectionInfo intersectionInfo) {
-
- }
+ /* The intersection point */
+ // Point3d getIntersectionPoint()
+
+ /* Distance between start point of pickShape and intersection point */
+ // double getDistance()
- /** Returns true if the geometry is indexed
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ /* The vertex indices of the intersected primitive in the geometry */
+ // int[] getVertexIndices()
- */
- public boolean geometryIsIndexed() {
- throw new UnsupportedOperationException();
- }
+ /*************************/
- /** Get coordinates of closest vertex (local)
- @return the coordinates of the vertex closest to the intersection point
+ /** Weight factors for interpolation, values correspond to vertex indices,
+ * sum == 1
+ */
+ private double[] interpWeights;
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ private static final boolean debug = false;
- */
- public Point3d getClosestVertexCoordinates () {
- throw new UnsupportedOperationException();
- }
+ // Axis constants
+ private static final int X_AXIS = 1;
+ private static final int Y_AXIS = 2;
+ private static final int Z_AXIS = 3;
- /** Get coordinates of closest vertex (world)
- @return the coordinates of the vertex closest to the intersection point
+ // Tolerance for numerical stability
+ static final double TOL = 1.0e-5;
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ /* 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;
- */
- public Point3d getClosestVertexCoordinatesVW () {
- throw new UnsupportedOperationException();
- }
+ private boolean hasColors;
+ private boolean hasNormals;
+ private boolean hasTexCoords;
- /** Get index of closest vertex
- @return the index of the closest vertex
+ // 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;
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ /* Local coordinates of the intersected primitive */
+ private Point3d[] primitiveCoordinates = null;
- */
- public int getClosestVertexIndex () {
- throw new UnsupportedOperationException();
- }
+ /** VWorld coordinates of intersected primitive */
+ private Point3d[] primitiveCoordinatesVW = null;
- /**
- Get the distance from the PickShape start point to the intersection point
- @return the distance to the intersection point, if available.
+ /* Normals of the intersected primitive */
+ private Vector3f[] primitiveNormals = null;
+
+ /* Colors of the intersected primitive */
+ private Color4f[] primitiveColors = null;
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ /* TextureCoordinates of the intersected primitive */
+ private TexCoord3f[] primitiveTexCoords = null;
- */
- public double getDistance () {
- throw new UnsupportedOperationException();
+ // 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;
+ }
/**
- 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.
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ * 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;
+ }
- */
- public Color4f getPointColor() {
- throw new UnsupportedOperationException();
+ /**
+ * 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 coordinates of the intersection point (local coordinates),
- if available.
- @return coordinates of the intersection point
+ * 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;
+ }
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
- */
+ /**
+ * Returns the coordinates of the intersection point (local coordinates),
+ * if available.
+ * @return coordinates of the intersection point
+ */
public Point3d getPointCoordinates() {
- throw new UnsupportedOperationException();
+ return pointCoordinates;
}
-
+
/**
- Returns the coordinates of the intersection point (world coordinates),
- if available.
- @return coordinates of the point
+ * Returns the coordinates of the intersection point (world coordinates),
+ * if available.
+ * @return coordinates of the point
+ */
+ public Point3d getPointCoordinatesVW() {
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ if (pointCoordinatesVW != null) {
+ return pointCoordinatesVW;
+ }
- */
- public Point3d getPointCoordinatesVW() {
- throw new UnsupportedOperationException();
+ 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.
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
+ * 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() {
- throw new UnsupportedOperationException();
+ 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.
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
+ * 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) {
- throw new UnsupportedOperationException();
+ 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
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public int[] getPrimitiveColorIndices () {
- throw new UnsupportedOperationException();
+ * 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)) {
+ if (geometryIsIndexed()) {
+ primitiveColorIndices =
+ new int[primitiveVertexIndices.length];
+ for (int i = 0; i < primitiveVertexIndices.length; i++) {
+ primitiveColorIndices[i] =
+ ((IndexedGeometryArray)(geometry)).getColorIndex(primitiveVertexIndices[i]);
+ }
+ } else {
+ primitiveColorIndices = primitiveVertexIndices;
+ }
+ }
+ return primitiveColorIndices;
}
/**
- Get the colors of the intersected primitive. This will return null if
- the primitive does not contain colors. If the geometry was defined
- using GeometryArray.COLOR_3, the 'w' value of the color will be set to 1.0.
- @return an array of Point3d's for the primitive that was intersected
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public Color4f[] getPrimitiveColors () {
- throw new UnsupportedOperationException();
+ * Get the colors of the intersected primitive. This will return null if
+ * the primitive does not contain colors. If the geometry was defined
+ * using GeometryArray.COLOR_3, the 'w' value of the color will be set to 1.0.
+ * @return an array of Point3d's for the primitive that was intersected
+ */
+ public Color4f[] getPrimitiveColors() {
+// System.out.println("PI.getPrimitiveColors " + primitiveColors);
+ GeometryArray geom = (GeometryArray) geometry;
+
+ if (hasColors && (primitiveColors == null)) {
+ primitiveColors = new Color4f[primitiveVertexIndices.length];
+ int[] indices = getPrimitiveColorIndices();
+ int vformat = geom.getVertexFormat();
+ if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
+ if ((vformat & GeometryArray.COLOR_4) ==
+ GeometryArray.COLOR_4) {
+ for (int i = 0; i < indices.length; i++) {
+ primitiveColors[i] = new Color4f();
+ geom.getColor(indices[i], primitiveColors[i]);
+ }
+ } else {
+ Color3f color = new Color3f();
+ for (int i = 0; i < indices.length; i++) {
+ primitiveColors[i] = new Color4f();
+ geom.getColor(indices[i], color);
+ primitiveColors[i].x = color.x;
+ primitiveColors[i].y = color.y;
+ primitiveColors[i].z = color.z;
+ primitiveColors[i].w = 1.0f;
+ }
+ }
+ }
+ else {
+ if ((vformat & GeometryArray.INTERLEAVED) == 0) {
+ float[] floatData = geom.getColorRefFloat();
+ // If data was set as float then ..
+ if (floatData == null) {
+ byte[] byteData = geom.getColorRefByte();
+ if (byteData == null) {
+ throw new UnsupportedOperationException("Deprecated : BY_REF - c3b and c3f");
+ }
+ else {
+ // Could be color3 or color4
+ int val;
+ if ((vformat & GeometryArray.COLOR_4) ==
+ GeometryArray.COLOR_4) {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] << 2; // for color4f
+ primitiveColors[i] = new Color4f(byteData[val],
+ byteData[val+1],
+ byteData[val+2],
+ byteData[val+3]);
+
+ }
+ }
+ else {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] * 3; // for color3f
+ primitiveColors[i] = new Color4f(byteData[val],
+ byteData[val+1],
+ byteData[val+2],
+ 1.0f);
+
+ }
+ }
+ }
+ }
+ else {
+ // Could be color3 or color4
+ int val;
+ if ((vformat & GeometryArray.COLOR_4) ==
+ GeometryArray.COLOR_4) {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] << 2; // for color4f
+ primitiveColors[i] = new Color4f(floatData[val],
+ floatData[val+1],
+ floatData[val+2],
+ floatData[val+3]);
+ }
+ }
+ else {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] * 3; // for color3f
+ primitiveColors[i] = new Color4f(floatData[val],
+ floatData[val+1],
+ floatData[val+2],
+ 1.0f);
+
+ }
+ }
+ }
+
+ }
+ else {
+ float[] floatData = geom.getInterleavedVertices();
+ int offset = getInterleavedColorOffset(geom);
+ int stride = getInterleavedStride(geom);
+ for (int i = 0; i < indices.length; i++) {
+ int val = stride * indices[i]+offset;
+ if ((vformat & GeometryArray.COLOR_4) ==
+ GeometryArray.COLOR_4) {
+ primitiveColors[i] = new Color4f(floatData[val],
+ floatData[val+1],
+ floatData[val+2],
+ floatData[val+3]);
+ }
+ else {
+ primitiveColors[i] = new Color4f(floatData[val],
+ floatData[val+1],
+ floatData[val+2],
+ 1.0f);
+ }
+ }
+ }
+ }
+ }
+ return primitiveColors;
}
/**
- Get the coordinates indices for the intersected primitive. For a non-indexed
- primitive, this will be the same as the primitive vertex indices
- @return an array indices
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public int[] getPrimitiveCoordinateIndices () {
- throw new UnsupportedOperationException();
+ * Get the coordinates indices for the intersected primitive. For a non-indexed
+ * primitive, this will be the same as the primitive vertex indices
+ * @return an array indices
+ */
+ public int[] getPrimitiveCoordinateIndices() {
+ if (primitiveCoordinateIndices == null) {
+ if (geometryIsIndexed()) {
+ primitiveCoordinateIndices =
+ new int[primitiveVertexIndices.length];
+ for (int i = 0; i < primitiveVertexIndices.length; i++) {
+ primitiveCoordinateIndices[i] =
+ ((IndexedGeometryArray)(geometry)).getCoordinateIndex(primitiveVertexIndices[i]);
+ }
+ } else {
+ primitiveCoordinateIndices = primitiveVertexIndices;
+ }
+ }
+ return primitiveCoordinateIndices;
}
/**
- Get the local coordinates intersected primitive
- @return an array of Point3d's for the primitive that was intersected
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public Point3d[] getPrimitiveCoordinates () {
- throw new UnsupportedOperationException();
+ * Get the local coordinates intersected primitive
+ * @return an array of Point3d's for the primitive that was intersected
+ */
+ public Point3d[] getPrimitiveCoordinates() {
+// System.out.println("PI.getPrimitiveCoordinates " + primitiveCoordinates);
+ GeometryArray geom = (GeometryArray) geometry;
+
+ if (primitiveCoordinates == null) {
+ primitiveCoordinates = new Point3d[primitiveVertexIndices.length];
+ int[] indices = getPrimitiveCoordinateIndices();
+ int vformat = geom.getVertexFormat();
+ int val;
+
+// System.out.println("---- indices.length - " + indices.length);
+ if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
+ for (int i = 0; i < indices.length; i++) {
+ primitiveCoordinates[i] = new Point3d();
+ // System.out.println("PickIntersection : indices["+i+"] = " + indices[i]);
+ geom.getCoordinate(indices[i], primitiveCoordinates[i]);
+ }
+ }
+ 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 - c3f and c3d");
+ }
+ else {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] * 3;
+ primitiveCoordinates[i] = new Point3d(floatData[val],
+ floatData[val+1],
+ floatData[val+2]);
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] * 3;
+ primitiveCoordinates[i] = 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 .
+ for (int i = 0; i < indices.length; i++) {
+ val = stride * indices[i]+offset;
+ primitiveCoordinates[i] = new Point3d(floatData[val],
+ floatData[val+1],
+ floatData[val+2]);
+ }
+ }
+ }
+
+ }
+ return primitiveCoordinates;
}
/**
- Get VWorld coordinates of the intersected primitive
- @return an array of Point3d's for the primitive that was picked
+ * Get VWorld coordinates of the intersected primitive
+ * @return an array of Point3d's for the primitive that was picked
+ */
+ public Point3d[] getPrimitiveCoordinatesVW() {
+
+// System.out.println("PI.getPrimitiveCoordinatesVW " + primitiveCoordinatesVW);
+
+ if (primitiveCoordinatesVW == null) {
+ // We need to call getPrimitiveCoordinates first.
+ Point3d[] coords = getPrimitiveCoordinates();
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ primitiveCoordinatesVW = new Point3d[coords.length];
+ for (int i = 0; i < coords.length; i++) {
+ primitiveCoordinatesVW[i] = new Point3d();
- */
- public Point3d[] getPrimitiveCoordinatesVW () {
- throw new UnsupportedOperationException();
+ primitiveCoordinatesVW[i].x = coords[i].x;
+ primitiveCoordinatesVW[i].y = coords[i].y;
+ primitiveCoordinatesVW[i].z = coords[i].z;
+
+ l2vw.transform(primitiveCoordinatesVW[i]);
+ }
+ }
+ return primitiveCoordinatesVW;
}
/**
- Get the normal 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 normals this will return null
- @return an array indices
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public int[] getPrimitiveNormalIndices () {
- throw new UnsupportedOperationException();
+ * Get the normal 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 normals this will return null
+ * @return an array indices
+ */
+ public int[] getPrimitiveNormalIndices() {
+ if (hasNormals && (primitiveNormalIndices == null)) {
+ if (geometryIsIndexed()) {
+ primitiveNormalIndices =
+ new int[primitiveVertexIndices.length];
+ for (int i = 0; i < primitiveVertexIndices.length; i++) {
+ primitiveNormalIndices[i] =
+ ((IndexedGeometryArray)(geometry)).getNormalIndex(primitiveVertexIndices[i]);
+ }
+ } else {
+ primitiveNormalIndices = primitiveVertexIndices;
+ }
+ }
+ return primitiveNormalIndices;
}
/**
- Get the normals of the intersected primitive. This will return null if
- the primitive does not contain normals.
- @return an array of Point3d's for the primitive that was intersected
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public Vector3f[] getPrimitiveNormals () {
- throw new UnsupportedOperationException();
+ * Get the normals of the intersected primitive. This will return null if
+ * the primitive does not contain normals.
+ * @return an array of Point3d's for the primitive that was intersected
+ */
+ public Vector3f[] getPrimitiveNormals() {
+// System.out.println("PI.getPrimitiveNormals " + primitiveNormals);
+ GeometryArray geom = (GeometryArray) geometry;
+
+ if (hasNormals && (primitiveNormals == null)) {
+ primitiveNormals = new Vector3f[primitiveVertexIndices.length];
+ int[] indices = getPrimitiveNormalIndices();
+ int vformat = geom.getVertexFormat();
+ int val;
+
+ if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
+ for (int i = 0; i < indices.length; i++) {
+ primitiveNormals[i] = new Vector3f();
+ geom.getNormal(indices[i], primitiveNormals[i]);
+ }
+ }
+ else {
+ if ((vformat & GeometryArray.INTERLEAVED) == 0) {
+ float[] floatNormals = geom.getNormalRefFloat();
+ if (floatNormals != null) {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] * 3;
+ primitiveNormals[i] = new Vector3f(floatNormals[val],
+ floatNormals[val+1],
+ floatNormals[val+2]);
+ }
+ }
+ else {
+ throw new UnsupportedOperationException("Deprecated : BY_REF - n3f");
+ }
+ }
+ else {
+ float[] floatData = geom.getInterleavedVertices();
+ int offset = getInterleavedColorOffset(geom);
+ int stride = getInterleavedStride(geom);
+ for (int i = 0; i < indices.length; i++) {
+ val = stride * indices[i]+offset;
+ primitiveNormals[i] = new Vector3f(floatData[val],floatData[val+1],floatData[val+2]);
+
+ }
+ }
+ }
+ }
+ return primitiveNormals;
}
/**
- Get the texture coordinate indices for the intersected primitive at the specifed
- index in the specified texture coordinate set. For a non-indexed
- primitive, this will be the same as the primitive vertex indices
- If the geometry array does not contain texture coordinates, this will
- return null.
- @return an array indices
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
- public int[] getPrimitiveTexCoordIndices (int index) {
- throw new UnsupportedOperationException();
+ * Get the texture coordinate indices for the intersected primitive at the specifed
+ * index in the specified texture coordinate set. For a non-indexed
+ * primitive, this will be the same as the primitive vertex indices
+ * If the geometry array does not contain texture coordinates, this will
+ * return null.
+ * @return an array indices
+ */
+ public int[] getPrimitiveTexCoordIndices(int index) {
+ if (hasTexCoords && (primitiveTexCoordIndices == null)) {
+ if (geometryIsIndexed()) {
+ primitiveTexCoordIndices =
+ new int[primitiveVertexIndices.length];
+ for (int i = 0; i < primitiveVertexIndices.length; i++) {
+ primitiveTexCoordIndices[i] =
+ ((IndexedGeometryArray)(geometry)).getTextureCoordinateIndex(index, primitiveVertexIndices[i]);
+ }
+ } else {
+ primitiveTexCoordIndices = primitiveVertexIndices;
+ }
+ }
+ return primitiveTexCoordIndices;
}
/**
- Get the texture coordinates of the intersected primitive at the specifed
- index in the specified texture coordinate set.
- null if the primitive does not contain texture coordinates.
- If the geometry was defined
- using GeometryArray.TEXTURE_COORDINATE_2, the 'z' value of the texture
- coordinate will be set to 0.0.
- @return an array of TexCoord3f's for the primitive that was intersected
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
-
- */
+ * Get the texture coordinates of the intersected primitive at the specifed
+ * index in the specified texture coordinate set.
+ * null if the primitive does not contain texture coordinates.
+ * If the geometry was defined
+ * using GeometryArray.TEXTURE_COORDINATE_2, the 'z' value of the texture
+ * coordinate will be set to 0.0.
+ * @return an array of TexCoord3f's for the primitive that was intersected
+ */
public TexCoord3f[] getPrimitiveTexCoords (int index) {
- throw new UnsupportedOperationException();
+// System.out.println("PI.getPrimitiveTexCoords " + primitiveTexCoords);
+ GeometryArray geom = (GeometryArray) geometry;
+
+ if (primitiveTexCoords == null) {
+ primitiveTexCoords = new TexCoord3f[primitiveVertexIndices.length];
+ int[] indices = getPrimitiveTexCoordIndices(index);
+ int vformat = geom.getVertexFormat();
+ if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
+ for (int i = 0; i < indices.length; i++) {
+ primitiveTexCoords[i] = new TexCoord3f();
+ geom.getTextureCoordinate(index, indices[i], primitiveTexCoords[i]);
+ }
+ }
+ else {
+ if ((vformat & GeometryArray.INTERLEAVED) == 0) {
+ int val;
+ float[] floatTexCoords = geom.getTexCoordRefFloat(index);
+ if (floatTexCoords != null) {
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] << 1; // t2f
+ primitiveTexCoords[i] = new TexCoord3f(floatTexCoords[val],
+ floatTexCoords[val+1],
+ 0.0f);
+ }
+ }
+ else {
+ for (int i = 0; i < indices.length; i++) {
+ val = indices[i] * 3; // t3f
+ primitiveTexCoords[i] = new TexCoord3f(floatTexCoords[val],
+ floatTexCoords[val+1],
+ floatTexCoords[val+2]);
+ }
+ }
+ }
+ else {
+ throw new UnsupportedOperationException("Deprecated : BY_REF - t2f and t3f");
+ }
+ }
+ else {
+ float[] floatData = geom.getInterleavedVertices();
+ int stride = getInterleavedStride(geom);
+ int offset;
+ // Get the correct tex coord set
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) ==
+ GeometryArray.TEXTURE_COORDINATE_2) {
+ offset = index << 1;
+ }
+ else {
+ offset = index * 3;
+ }
+ for (int i = 0; i < indices.length; i++) {
+ int val = stride * indices[i];
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) ==
+ GeometryArray.TEXTURE_COORDINATE_2) {
+ primitiveTexCoords[i] =
+ new TexCoord3f(floatData[val+offset],
+ floatData[val+1+offset],
+ 0.0f);
+ }
+ else {
+ primitiveTexCoords[i] =
+ new TexCoord3f(floatData[val+offset],
+ floatData[val+1+offset],
+ floatData[val+2+offset]);
+ }
+ }
+ }
+ }
+ }
+ return primitiveTexCoords;
}
/**
- Get vertex indices of the intersected primitive
- @return an array which contains the list of indices
-
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ * Get vertex indices of the intersected primitive
+ * @return an array which contains the list of indices
+ */
+ public int [] getPrimitiveVertexIndices() {
+ return primitiveVertexIndices;
+ }
- */
- public int [] getPrimitiveVertexIndices () {
- throw new UnsupportedOperationException();
+ /**
+ * Gets the IntersectionInfo this intersection is part of.
+ */
+ public PickInfo.IntersectionInfo getIntersectionInfo() {
+ return iInfo;
}
/**
- String representation of this object
+ * String representation of this object
+ */
+ public String toString() {
+ String rt = new String ("PickIntersection: ");
+ rt += " IntersectionInfo = "+ iInfo + "\n";
+ rt += " geometry = "+ geometry + "\n";
+ if (distance != -1) rt += " dist:"+distance + "\n";
+ if (pointCoordinates != null) rt += " pt:" + pointCoordinates + "\n";
+ if (pointCoordinatesVW != null) rt += " ptVW:" + pointCoordinatesVW + "\n";
+
+ if (primitiveCoordinateIndices != null) {
+ rt += " prim coordinate ind:" + "\n";
+ for (int i=0;i<primitiveCoordinateIndices.length;i++) {
+ rt += " "+primitiveCoordinateIndices[i] + "\n";
+ }
+ }
+
+ if (primitiveColorIndices != null) {
+ rt += " prim color ind:" + "\n";
+ for (int i=0;i<primitiveColorIndices.length;i++) {
+ rt += " "+primitiveColorIndices[i] + "\n";
+ }
+ }
+
+ if (primitiveNormalIndices != null) {
+ rt += " prim normal ind:" + "\n";
+ for (int i=0;i<primitiveNormalIndices.length;i++) {
+ rt += " "+primitiveNormalIndices[i] + "\n";
+ }
+ }
+
+ if (primitiveTexCoordIndices != null) {
+ rt += " prim texture ind:" + "\n";
+ for (int i=0;i<primitiveTexCoordIndices.length;i++) {
+ rt += " "+primitiveTexCoordIndices[i] + "\n";
+ }
+ }
+
+ if (closestVertexCoordinates != null) {
+ rt += " clos. vert:" + closestVertexCoordinates + "\n";
+ }
+
+ if (closestVertexCoordinatesVW != null) {
+ rt += " clos. vert:" + closestVertexCoordinatesVW + "\n";
+ }
+
+ if (closestVertexIndex != -1) {
+ rt += " clos. vert. ind.:" + closestVertexIndex + "\n";
+ }
+ return rt;
+ }
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
- */
- public String toString () {
- throw new UnsupportedOperationException();
- }
+ /******************** Helper methods ***************************************/
- /**
- Gets the IntersectionInfo this intersection is part of.
+ int getInterleavedVertexOffset(GeometryArray geo) {
+ int offset = 0;
+ int vformat = geo.getVertexFormat();
+ if ((vformat & GeometryArray.COLOR_3) == GeometryArray.COLOR_3) {
+ offset += 3;
+ } else if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4){
+ offset += 4;
+ }
+ if ((vformat & GeometryArray.NORMALS) != 0)
+ offset += 3;
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
+ offset += 2 * geo.getTexCoordSetCount();
+ }
+ else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
+ offset += 3 * geo.getTexCoordSetCount();
+ }
- * This method is currently not supported.
- * @exception UnsupportedOperationException this method is not supported
+ return offset;
+ }
- */
- public PickInfo.IntersectionInfo getIntersectionInfo() {
- throw new UnsupportedOperationException();
+ int getInterleavedStride(GeometryArray geo) {
+ int offset = 3; // Add 3 for vertices
+ int vformat = geo.getVertexFormat();
+ if ((vformat & GeometryArray.COLOR_3) == GeometryArray.COLOR_3) {
+ offset += 3;
+ } else if ((vformat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4){
+ offset += 4;
+ }
+ if ((vformat & GeometryArray.NORMALS) != 0)
+ offset += 3;
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
+ offset += 2 * geo.getTexCoordSetCount();
+ }
+ else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
+ offset += 3 * geo.getTexCoordSetCount();
+ }
+
+ return offset;
}
-
-} // PickIntersection
+ int getInterleavedColorOffset(GeometryArray geo) {
+ int offset = 0;
+ int vformat = geo.getVertexFormat();
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) == GeometryArray.TEXTURE_COORDINATE_2) {
+ offset += 2 * geo.getTexCoordSetCount();
+ }
+ else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) == GeometryArray.TEXTURE_COORDINATE_3) {
+ offset += 3 * geo.getTexCoordSetCount();
+ }
+
+ return offset;
+ }
+ /* ================================================================== */
+ /* Utility code for interpolating intersection point data */
+ /* ================================================================== */
+ /* absolute value */
+ double
+ abs(double value) {
+ if (value < 0.0) {
+ return -value;
+ } else {
+ return value;
+ }
+ }
+
+ /* return the axis corresponding to the largest component of delta */
+ int
+ maxAxis(Vector3d delta) {
+ int axis = X_AXIS;
+ double max = abs(delta.x);
+ if (abs(delta.y) > max) {
+ axis = Y_AXIS;
+ max = abs(delta.y);
+ }
+ if (abs(delta.z) > max) {
+ axis = Z_AXIS;
+ }
+ return axis;
+ }
+ /* Triangle interpolation. Basic idea:
+ * Map the verticies of the triangle to the form:
+ *
+ * L--------R
+ * \ /
+ * IL+--P-+IR
+ * \ /
+ * Base
+ *
+ where P is the intersection point Base, L and R and the triangle
+ points. IL and IR are the projections if P along the Base-L and Base-R
+ edges using an axis:
+
+ IL = leftFactor * L + (1- leftFactor) * Base
+ IR = rightFactor * R + (1-rightFactor) * Base
+
+ then find the interp factor, midFactor, for P between IL and IR. If
+ this is outside the range 0->1 then we have the wrong triangle of a
+ quad and we return false.
+
+ Else, the weighting is:
+
+ IP = midFactor * IL + (1 - midFactor) * IR;
+
+ Solving for weights for the formula:
+ IP = BaseWeight * Base + LeftWeight * L + RightWeight * R;
+ We get:
+ BaseWeight = 1 - midFactor * leftFactor
+ - rightFactor + midFactor * rightFactor;
+ LeftWeight = midFactor * leftFactor;
+ RightWeight = righFactor - midFactor * rightFactor;
+ As a check, note that the sum of the weights is 1.0.
+ */
+
+ boolean
+ interpTriangle(int index0, int index1, int index2, Point3d[] coords,
+ Point3d intPt) {
+
+ // find the longest edge, we'll use that to pick the axis */
+ Vector3d delta0 = new Vector3d();
+ Vector3d delta1 = new Vector3d();
+ Vector3d delta2 = new Vector3d();
+ delta0.sub(coords[index1], coords[index0]);
+ delta1.sub(coords[index2], coords[index0]);
+ delta2.sub(coords[index2], coords[index1]);
+ double len0 = delta0.lengthSquared();
+ double len1 = delta1.lengthSquared();
+ double len2 = delta2.lengthSquared();
+ Vector3d longest = delta0;
+ double maxLen = len0;
+ if (len1 > maxLen) {
+ longest = delta1;
+ maxLen = len1;
+ }
+ if (len2 > maxLen) {
+ longest = delta2;
+ }
+ int mainAxis = maxAxis(longest);
+
+ /*
+ System.out.println("index0 = " + index0 + " index1 = " + index1 +
+ " index2 = " + index2);
+
+ System.out.println("coords[index0] = " + coords[index0]);
+ System.out.println("coords[index1] = " + coords[index1]);
+ System.out.println("coords[index2] = " + coords[index2]);
+ System.out.println("intPt = " + intPt);
+
+ System.out.println("delta0 = " + delta0 + " len0 " + len0);
+ System.out.println("delta1 = " + delta1 + " len1 " + len1);
+ System.out.println("delta2 = " + delta2 + " len2 " + len2);
+ */
+
+ /* now project the intersection point along the axis onto the edges */
+ double[] factor = new double[3];
+ /* the factor is for the projection opposide the vertex 0 = 1->2, etc*/
+ factor[0] =
+ getInterpFactorForBase(intPt, coords[index1], coords[index2], mainAxis);
+ factor[1] =
+ getInterpFactorForBase(intPt, coords[index2], coords[index0], mainAxis);
+ factor[2] =
+ getInterpFactorForBase(intPt, coords[index0], coords[index1], mainAxis);
+
+ if (debug) {
+ System.out.println("intPt = " + intPt);
+ switch(mainAxis) {
+ case X_AXIS:
+ System.out.println("mainAxis = X_AXIS");
+ break;
+ case Y_AXIS:
+ System.out.println("mainAxis = Y_AXIS");
+ break;
+ case Z_AXIS:
+ System.out.println("mainAxis = Z_AXIS");
+ break;
+ }
+ System.out.println("factor[0] = " + factor[0]);
+ System.out.println("factor[1] = " + factor[1]);
+ System.out.println("factor[2] = " + factor[2]);
+ }
+
+ /* Find the factor that is out of range, it will tell us which
+ * vertex to use for base
+ */
+ int base, left, right;
+ double leftFactor, rightFactor;
+ if ((factor[0] < 0.0) || (factor[0] > 1.0)) {
+ base = index0;
+ right = index1;
+ left = index2;
+ rightFactor = factor[2];
+ leftFactor = 1.0 - factor[1];
+ if (debug) {
+ System.out.println("base 0, rightFactor = " + rightFactor +
+ " leftFactor = " + leftFactor);
+ }
+ } else if ((factor[1] < 0.0) || (factor[1] > 1.0)) {
+ base = index1;
+ right = index2;
+ left = index0;
+ rightFactor = factor[0];
+ leftFactor = 1.0 - factor[2];
+ if (debug) {
+ System.out.println("base 1, rightFactor = " + rightFactor +
+ " leftFactor = " + leftFactor);
+ }
+ } else {
+ base = index2;
+ right = index0;
+ left = index1;
+ rightFactor = factor[1];
+ leftFactor = 1.0 - factor[0];
+ if (debug) {
+ System.out.println("base 2, rightFactor = " + rightFactor +
+ " leftFactor = " + leftFactor);
+ }
+ }
+ if (debug) {
+ System.out.println("base = " + coords[base]);
+ System.out.println("left = " + coords[left]);
+ System.out.println("right = " + coords[right]);
+ }
+ /* find iLeft and iRight */
+ Point3d iLeft = new Point3d(leftFactor * coords[left].x +
+ (1.0-leftFactor)*coords[base].x,
+ leftFactor * coords[left].y +
+ (1.0-leftFactor)*coords[base].y,
+ leftFactor * coords[left].z +
+ (1.0-leftFactor)*coords[base].z);
+
+ Point3d iRight = new Point3d(rightFactor * coords[right].x +
+ (1.0-rightFactor)*coords[base].x,
+ rightFactor * coords[right].y +
+ (1.0-rightFactor)*coords[base].y,
+ rightFactor * coords[right].z +
+ (1.0-rightFactor)*coords[base].z);
+
+ if (debug) {
+ System.out.println("iLeft = " + iLeft);
+ System.out.println("iRight = " + iRight);
+ }
+
+ /* now find an axis and solve for midFactor */
+ delta0.sub(iLeft, iRight);
+ int midAxis = maxAxis(delta0);
+ double midFactor = getInterpFactor(intPt, iRight, iLeft, midAxis);
+
+ if (debug) {
+ switch(midAxis) {
+ case X_AXIS:
+ System.out.println("midAxis = X_AXIS");
+ break;
+ case Y_AXIS:
+ System.out.println("midAxis = Y_AXIS");
+ break;
+ case Z_AXIS:
+ System.out.println("midAxis = Z_AXIS");
+ break;
+ }
+ System.out.println("midFactor = " + midFactor);
+ }
+
+ if (midFactor < 0.0) {
+ // System.out.println("midFactor = " + midFactor);
+ if ((midFactor + TOL) >= 0.0) {
+ // System.out.println("In Tol case : midFactor = " + midFactor);
+ midFactor = 0.0;
+ }
+ else {
+ /* int point is outside triangle */
+ return false;
+ }
+ }
+ else if (midFactor > 1.0) {
+ // System.out.println("midFactor = " + midFactor);
+ if ((midFactor-TOL) <= 1.0) {
+ // System.out.println("In Tol case : midFactor = " + midFactor);
+ midFactor = 1.0;
+ }
+ else {
+ /* int point is outside triangle */
+ return false;
+ }
+ }
+
+ // Assign the weights
+ interpWeights[base] = 1.0 - midFactor * leftFactor -
+ rightFactor + midFactor * rightFactor;
+ interpWeights[left] = midFactor * leftFactor;
+ interpWeights[right] = rightFactor - midFactor * rightFactor;
+ return true;
+ }
+ /* Get the interpolation weights for each of the verticies of the
+ * primitive.
+ */
+ double[] getInterpWeights() {
+
+ Point3d pt = getPointCoordinates();
+ Point3d[] coordinates = getPrimitiveCoordinates();
+ double factor;
+ int axis;
+
+ if (interpWeights != null) {
+ return interpWeights;
+ }
+
+ interpWeights = new double[coordinates.length];
+
+ // Interpolate
+ switch (coordinates.length) {
+ case 1:
+ // Nothing to interpolate
+ interpWeights[0] = 1.0;
+ break;
+ case 2: // edge
+ Vector3d delta = new Vector3d();
+ delta.sub (coordinates[1], coordinates[0]);
+ axis = maxAxis(delta);
+ factor = getInterpFactor (pt, coordinates[1], coordinates[0], axis);
+ interpWeights[0] = factor;
+ interpWeights[1] = 1.0 - factor;
+ break;
+ case 3: // triangle
+ if (!interpTriangle(0, 1, 2, coordinates, pt)) {
+ throw new RuntimeException ("Interp point outside triangle");
+ }
+ break;
+ case 4: // quad
+ if (!interpTriangle(0, 1, 2, coordinates, pt)) {
+ if (!interpTriangle(0, 2, 3, coordinates, pt)) {
+ throw new RuntimeException ("Interp point outside quad");
+ }
+ }
+ break;
+ default:
+ throw new RuntimeException ("Unexpected number of points.");
+ }
+ return interpWeights;
+ }
+ /**
+ Calculate the interpolation factor for point p by projecting it along
+ an axis (x,y,z) onto the edge between p1 and p2. If the result is
+ in the 0->1 range, point is between p1 and p2 (0 = point is at p1,
+ 1 => point is at p2).
+ */
+ private static float getInterpFactor (Point3d p, Point3d p1, Point3d p2,
+ int axis) {
+ float t;
+ switch (axis) {
+ case X_AXIS:
+ if (p1.x == p2.x)
+ //t = Float.MAX_VALUE; // TODO: should be 0?
+ t = 0.0f;
+ else
+ t = (float) ((p1.x - p.x) / (p1.x - p2.x));
+ break;
+ case Y_AXIS:
+ if (p1.y == p2.y)
+ // t = Float.MAX_VALUE;
+ t = 0.0f;
+ else
+ t = (float) ((p1.y - p.y) / (p1.y - p2.y));
+ break;
+ case Z_AXIS:
+ if (p1.z == p2.z)
+ // t = Float.MAX_VALUE;
+ t = 0.0f;
+ else
+ t = (float)((p1.z - p.z) / (p1.z - p2.z));
+ break;
+ default:
+ throw new RuntimeException ("invalid axis parameter "+axis+" (must be 0-2)");
+ }
+ return t;
+ }
+ /**
+ Calculate the interpolation factor for point p by projecting it along
+ an axis (x,y,z) onto the edge between p1 and p2. If the result is
+ in the 0->1 range, point is between p1 and p2 (0 = point is at p1,
+ 1 => point is at p2).
+ return MAX_VALUE if component of vertices are the same.
+ */
+ private static float getInterpFactorForBase (Point3d p, Point3d p1, Point3d p2,
+ int axis) {
+ float t;
+ switch (axis) {
+ case X_AXIS:
+ if (p1.x == p2.x)
+ t = Float.MAX_VALUE;
+ else
+ t = (float) ((p1.x - p.x) / (p1.x - p2.x));
+ break;
+ case Y_AXIS:
+ if (p1.y == p2.y)
+ t = Float.MAX_VALUE;
+ else
+ t = (float) ((p1.y - p.y) / (p1.y - p2.y));
+ break;
+ case Z_AXIS:
+ if (p1.z == p2.z)
+ t = Float.MAX_VALUE;
+ else
+ t = (float)((p1.z - p.z) / (p1.z - p2.z));
+ break;
+ default:
+ throw new RuntimeException ("invalid axis parameter "+axis+" (must be 0-2)");
+ }
+ return t;
+ }
+
+} // PickIntersection