/** {@inheritDoc} */
  public Vector3f getIntersection(Ray ray, Spatial parent, Vector3f store, boolean local) {
    if (store == null) {
      store = new Vector3f();
    }

    TrianglePickResults results = new TrianglePickResults();
    results.setCheckDistance(true);
    Vector3f[] vertices = new Vector3f[3];
    parent.findPick(ray, results);
    boolean hit = false;
    if (results.getNumber() > 0) {
      PickData data = results.getPickData(0);
      ArrayList<Integer> triangles = data.getTargetTris();
      if (!triangles.isEmpty()) {
        TriMesh mesh = (TriMesh) data.getTargetMesh();
        mesh.getTriangle(triangles.get(0).intValue(), vertices);
        for (int j = 0; j < vertices.length; j++) {
          mesh.localToWorld(vertices[j], vertices[j]);
        }
        hit = ray.intersectWhere(vertices[0], vertices[1], vertices[2], store);
        if (hit && local) {
          parent.worldToLocal(store, store);
          return store;
        } else if (hit && !local) {
          return store;
        }
      }
    }

    return null;
  }
  public Vector3f getDestination(float x1, float z1, float x2, float z2, Spatial spatial) {
    // generate the start and destination points
    Vector3f start = new Vector3f(x1, EStats.SnowmanHeight.getValue() / 2.0f, z1);
    Vector3f destination = new Vector3f(x2, EStats.SnowmanHeight.getValue() / 2.0f, z2);

    // convert points to world coordinate system
    spatial.localToWorld(start, start);
    spatial.localToWorld(destination, destination);

    // generate Ray for intersection detection
    Vector3f direction = destination.subtract(start).normalizeLocal();
    Ray moveRay = new Ray(start, direction);

    // calculate the intersection between the move ray and the spatial
    Vector3f hitPoint = getIntersection(moveRay, spatial, null, false);

    // if there are no obstacles, return the destination directly
    if (hitPoint == null) {
      spatial.worldToLocal(destination, destination);
      return destination;
    } else {
      float originalDistance = destination.distance(start);
      float newDistance = hitPoint.distance(start);

      if (originalDistance > newDistance - EStats.BackoffDistance.getValue()) {
        // we are either trying to go through a hit point
        // or got too close to one
        direction.multLocal(EStats.BackoffDistance.getValue());
        Vector3f newDestination = hitPoint.subtractLocal(direction);
        spatial.worldToLocal(newDestination, newDestination);
        return newDestination;
      } else {
        // destination is not close to any hit points so
        // we can just return it directly
        spatial.worldToLocal(destination, destination);
        return destination;
      }
    }
  }