/**
  * Find out where on the terrain surface the eye would be looking at with the given heading and
  * pitch angles.
  *
  * @param view the orbit view
  * @param heading heading direction clockwise from north.
  * @param pitch view pitch angle from the surface normal at the center point.
  * @return the terrain surface point the view would be looking at in the viewport center.
  */
 protected Vec4 computeSurfacePoint(OrbitView view, Angle heading, Angle pitch) {
   Globe globe = wwd.getModel().getGlobe();
   // Compute transform to be applied to north pointing Y so that it would point in the view
   // direction
   // Move coordinate system to view center point
   Matrix transform = globe.computeSurfaceOrientationAtPosition(view.getCenterPosition());
   // Rotate so that the north pointing axes Y will point in the look at direction
   transform = transform.multiply(Matrix.fromRotationZ(heading.multiply(-1)));
   transform = transform.multiply(Matrix.fromRotationX(Angle.NEG90.add(pitch)));
   // Compute forward vector
   Vec4 forward = Vec4.UNIT_Y.transformBy4(transform);
   // Return intersection with terrain
   Intersection[] intersections =
       wwd.getSceneController().getTerrain().intersect(new Line(view.getEyePoint(), forward));
   return (intersections != null && intersections.length != 0)
       ? intersections[0].getIntersectionPoint()
       : null;
 }
  /**
   * Indicates the transform matrix applied to this document.
   *
   * @return Transform matrix.
   */
  protected Matrix getMatrix() {
    // If the matrix has already been computed then just return the cached value.
    if (this.matrix != null) return this.matrix;

    Matrix m = Matrix.IDENTITY;

    if (this.heading != null)
      m = m.multiply(Matrix.fromRotationZ(Angle.POS360.subtract(this.heading)));

    if (this.pitch != null) m = m.multiply(Matrix.fromRotationX(this.pitch));

    if (this.roll != null) m = m.multiply(Matrix.fromRotationY(this.roll));

    // Apply scaling factor to convert file units to meters.
    double scale = this.getScale();
    m = m.multiply(Matrix.fromScale(scale));

    if (this.modelScale != null) m = m.multiply(Matrix.fromScale(this.modelScale));

    this.matrix = m;
    return m;
  }