/**
   * Check if the geometry component of this shape node under path intersects with the pickRay.
   *
   * @return true if intersected else false. If return is true, dist contains the closest distance
   *     of intersection.
   * @exception IllegalArgumentException if <code>path</code> is invalid.
   */
  boolean intersect(SceneGraphPath path, PickShape pickShape, double[] dist) {

    int flags;
    PickInfo pickInfo = new PickInfo();

    Transform3D localToVworld = path.getTransform();
    if (localToVworld == null) {
      throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained3"));
    }
    pickInfo.setLocalToVWorldRef(localToVworld);

    Shape3D shape = (Shape3D) path.getObject();
    // Get the geometries for this shape only, since the compiled
    // geomtryList contains several shapes
    ArrayList glist = (ArrayList) geometryInfo.get(shape.id);

    // System.err.println("Shape3DCompileRetained.intersect() : ");
    if (dist == null) {
      // System.err.println("      no dist request ....");
      return intersect(pickInfo, pickShape, 0, glist);
    }

    flags = PickInfo.CLOSEST_DISTANCE;
    if (intersect(pickInfo, pickShape, flags, glist)) {
      dist[0] = pickInfo.getClosestDistance();
      return true;
    }

    return false;
  }
  boolean intersect(PickInfo pickInfo, PickShape pickShape, int flags, ArrayList geometryList) {

    Transform3D localToVworld = pickInfo.getLocalToVWorldRef();

    Transform3D t3d = new Transform3D();
    t3d.invert(localToVworld);
    PickShape newPS = pickShape.transform(t3d);

    int geomListSize = geometryList.size();
    GeometryRetained geometry;

    if (((flags & PickInfo.CLOSEST_INTERSECTION_POINT) == 0)
        && ((flags & PickInfo.CLOSEST_DISTANCE) == 0)
        && ((flags & PickInfo.CLOSEST_GEOM_INFO) == 0)
        && ((flags & PickInfo.ALL_GEOM_INFO) == 0)) {

      for (int i = 0; i < geomListSize; i++) {
        geometry = (GeometryRetained) geometryList.get(i);
        if (geometry != null) {
          if (geometry.mirrorGeometry != null) {
            geometry = geometry.mirrorGeometry;
          }
          // Need to modify this method
          // if (geometry.intersect(newPS, null, null)) {
          if (geometry.intersect(newPS, null, 0, null, null, 0)) {
            return true;
          }
        }
      }
    } else {
      double distance;
      double minDist = Double.POSITIVE_INFINITY;
      Point3d closestIPnt = new Point3d();
      Point3d iPnt = new Point3d();
      Point3d iPntVW = new Point3d();

      for (int i = 0; i < geomListSize; i++) {
        geometry = (GeometryRetained) geometryList.get(i);
        if (geometry != null) {
          if (geometry.mirrorGeometry != null) {
            geometry = geometry.mirrorGeometry;
          }
          if (geometry.intersect(newPS, pickInfo, flags, iPnt, geometry, i)) {

            iPntVW.set(iPnt);
            localToVworld.transform(iPntVW);
            distance = pickShape.distance(iPntVW);

            if (minDist > distance) {
              minDist = distance;
              closestIPnt.set(iPnt);
            }
          }
        }
      }

      if (minDist < Double.POSITIVE_INFINITY) {
        if ((flags & PickInfo.CLOSEST_DISTANCE) != 0) {
          pickInfo.setClosestDistance(minDist);
        }
        if ((flags & PickInfo.CLOSEST_INTERSECTION_POINT) != 0) {
          pickInfo.setClosestIntersectionPoint(closestIPnt);
        }
        return true;
      }
    }

    return false;
  }