📄 pickintersection.java
字号:
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; } /******************** Helper methods ***************************************/ 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(); } return offset; } 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; } 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -