@Override
  public void computeTransform(RigidBodyTransform currXform) {
    update();
    CameraMountInterface cameraMount = getCameraMount();
    if (isMounted() && (cameraMount != null)) {
      cameraMount.getTransformToCamera(currXform);

      return;
    }

    positionOffset.set(getCamX(), getCamY(), getCamZ());
    xAxis.set(getFixX(), getFixY(), getFixZ());

    fixPointNode.translateTo(getFixX(), getFixY(), getFixZ());

    xAxis.sub(positionOffset);
    xAxis.normalize();
    zAxis.set(0.0, 0.0, 1.0);
    yAxis.cross(zAxis, xAxis);
    zAxis.cross(xAxis, yAxis);

    rotationMatrix.setColumn(0, xAxis);
    rotationMatrix.setColumn(1, yAxis);
    rotationMatrix.setColumn(2, zAxis);

    currXform.setRotationAndZeroTranslation(rotationMatrix);
    currXform.setTranslation(positionOffset);
    currXform.normalizeRotationPart();
  }
  public void doMouseDraggedRight(double dx, double dy) {
    // Elevate up and down
    double delX0 = camX - fixX, delY0 = camY - fixY, delZ0 = camZ - fixZ;
    v3d.set(delX0, delY0, delZ0);

    // double offsetDistance = v3d.length();

    t3d.setRotationYawAndZeroTranslation(-dx * rotate_camera_factor);
    t3d.transform(v3d);

    if (!isTracking || (!isTrackingX && !isTrackingY)) {
      fixX = camX - v3d.getX();
      fixY = camY - v3d.getY();
    }

    delX0 = camX - fixX;
    delY0 = camY - fixY;
    delZ0 = camZ - fixZ;

    // v3d.set(delX0, delY0, delZ0);

    rotVector.set(-1.0, 0.0, 0.0);
    rotVector.cross(new Vector3d(0.0, 0.0, -1.0), v3d);
    rotAxisAngle4d.set(rotVector, dy * rotate_camera_factor / 4.0);

    t3d.setRotationAndZeroTranslation(rotAxisAngle4d);
    t3d.transform(v3d);

    if ((v3d.getX() * delX0 > 0.0) && (v3d.getY() * delY0 > 0.0)) {
      if (!isTracking || (!isTrackingX && !isTrackingY)) {
        fixX = camX - v3d.getX();
        fixY = camY - v3d.getY();
      }

      if (!isTracking || !isTrackingZ) {
        fixZ = camZ - v3d.getZ();

        /*
         * double factor = elevate_camera_factor * offsetDistance;
         * //Math.abs(camZ-fixZ); if (factor < elevate_camera_factor) factor
         * = elevate_camera_factor; fixZ = camZ - v3d.z + dy factor; //fixZ
         * = camZ - v3d.z + dy * elevate_factor;
         */
      }
    }

    // transformChanged(currXform);
  }
  public void doMouseDraggedLeft(double dx, double dy) {
    // Rotate around fix point:

    double delX0 = camX - fixX, delY0 = camY - fixY, delZ0 = camZ - fixZ;
    v3d.set(delX0, delY0, delZ0);

    // double offsetDistance = v3d.length();

    t3d.setRotationYawAndZeroTranslation(-dx * rotate_factor);
    t3d.transform(v3d);

    if (!isDolly || (!isDollyX && !isDollyY)) {
      camX = v3d.getX() + fixX;
      camY = v3d.getY() + fixY;
    }

    delX0 = camX - fixX;
    delY0 = camY - fixY;
    delZ0 = camZ - fixZ;

    // v3d.set(delX0, delY0, delZ0);
    rotVector.cross(new Vector3d(0.0, 0.0, -1.0), v3d);
    rotAxisAngle4d.set(rotVector, dy * rotate_factor / 4.0);

    t3d.setRotationAndZeroTranslation(rotAxisAngle4d);
    t3d.transform(v3d);

    if ((v3d.getX() * delX0 > 0.0) && (v3d.getY() * delY0 > 0.0)) {
      if (!isDolly || (!isDollyX && !isDollyY)) {
        camX = v3d.getX() + fixX;
        camY = v3d.getY() + fixY;
      }

      if (!isDolly || !isDollyZ) {
        camZ = v3d.getZ() + fixZ;

        /*
         * double factor = elevate_factor * Math.abs(offsetDistance);
         * //camZ-fixZ); if (factor < elevate_factor) factor =
         * elevate_factor; //camZ = v3d.z + fixZ + dy * elevate_factor; camZ
         * = v3d.z + fixZ + dy * factor;
         */
      }
    }

    // transformChanged(currXform);
  }
  public void rotateAroundFix(double dx, double dy) {
    double distanceFromCameraToFix =
        Math.sqrt(Math.pow(camX - fixX, 2) + Math.pow(camY - fixY, 2) + Math.pow(camZ - fixZ, 2));

    if (distanceFromCameraToFix > 1.0) {
      dx /= distanceFromCameraToFix;
      dy /= distanceFromCameraToFix;
    }

    double delX0 = camX - fixX, delY0 = camY - fixY, delZ0 = camZ - fixZ;
    v3d.set(delX0, delY0, delZ0);

    t3d.setRotationYawAndZeroTranslation(-dx * rotate_factor);
    t3d.transform(v3d);

    if (!isDolly || (!isDollyX && !isDollyY)) {
      camX = v3d.getX() + fixX;
      camY = v3d.getY() + fixY;
    }

    delX0 = camX - fixX;
    delY0 = camY - fixY;
    delZ0 = camZ - fixZ;

    rotVector.cross(new Vector3d(0.0, 0.0, -1.0), v3d);
    rotAxisAngle4d.set(rotVector, dy * rotate_factor / 4.0);

    t3d.setRotationAndZeroTranslation(rotAxisAngle4d);
    t3d.transform(v3d);

    if ((v3d.getX() * delX0 > 0.0) && (v3d.getY() * delY0 > 0.0)) {
      if (!isDolly || (!isDollyX && !isDollyY)) {
        camX = v3d.getX() + fixX;
        camY = v3d.getY() + fixY;
      }

      if (!isDolly || !isDollyZ) {
        camZ = v3d.getZ() + fixZ;
      }
    }
  }