glob3mobile / g3m

The multiplatform advanced visualization framework
http://www.glob3mobile.com/
Other
117 stars 56 forks source link

CAMERA ERROR: center point does not intersect globe #69

Closed ztreer closed 10 years ago

ztreer commented 10 years ago

Hi!

We've found another confusing issue.

In our app we use multiple camera modes:

The problem arised because in replay and sensor modes the roll is also set to non-zero values, which works as expected. However when switching back to manual mode the previous roll is kept, and there is no way to manually 'reset' the roll, as no mouse gesture is bound to that. Also a high pitch (looking up, so you cannot see the ground) makes manual mode unusable, as you cannot actually drag on the planet.

Therefore we've tried to reset roll and pitch when switching back to manual mode (and keep the heading only), but a surprising error occurred: some of the touch gestures stopped working (scrolling was ok, but zooming/rotating and setting pitch did not).

Code we used to reset: TaitBryanAngles hpr = g3mWidget.getCurrentCamera().getHeadingPitchRoll(); g3mWidget.setCameraHeadingPitchRoll(hpr._heading, Angle.fromDegrees(0.0), Angle.fromDegrees(0.0) );

We've tried to run the above code embedded in a GTask - using threadUtils.invokeInRendererThread, and also without it. It seemed to make no difference.

It turned out that we created some internal inconsistency by that, which causes "CAMERA ERROR: center point does not intersect globe" type errors later.

It is important to note that there were no problems while setting the camera from code (even when the globe was not visible on screen), also resetting the pitch and roll did happen, and the result of that was visible on screen.

But after that touch events would cause the above mentioned error.

Error comes from org.glob3.mobile.generated.CameraRotationHandler, line 119:

// compute center of view
_pivotPoint = camera.getXYZCenterOfView().asMutableVector3D();
if (_pivotPoint.isNan())
{
  ILogger.instance().logError("CAMERA ERROR: center point does not intersect globe!!\n");
  cameraContext.setCurrentGesture(Gesture.None);
}

My theories were along the lines of

Do you have any ideas?

Thank you !

DiegoGomezDeck commented 10 years ago

Hello @ztreer

I had a similar situation (expect I didn't need roll resetting). The problem is that some touch-events handlers requires that the center of the view doesn't show the sky but the earth.

I used this workaround when going back to manual-mode.

private void hackCameraPitch() { // change the camera pitch to avoid a bug in CameraHandler that doesn't allow to pitch the camera in this situation (DGD)

  final Camera camera = _g3mWidget.getCurrentCamera();
  final Angle cameraPitch = camera.getPitch();

  if (cameraPitch._degrees >= -6) {
     final Geodetic3D cameraPosition = camera.getGeodeticPosition();
     final Geodetic3D position = new Geodetic3D( //
              cameraPosition._latitude, //
              cameraPosition._longitude, //
              cameraPosition._height + 1000);

     _g3mWidget.setAnimatedCameraPosition( //
              TimeInterval.fromSeconds(0.1), //
              position, //
              camera.getHeading(), //
              Angle.fromDegrees(-6), //
              false, // linearTiming
              true /* linearHeight */);
  }

}

DiegoGomezDeck commented 10 years ago

There are also a CameraActivityListener, where your code can be notified when the user touches the screen (useful if you want switch to user-controlled mode when the user touches the screen).

  builder.setCameraActivityListener(new ICameraActivityListener() {
     @Override
     public void touchEventHandled() {
        setManualControlViewMode();  // test if the system is in manual-control mode or not, and hack the camera pitch if needed
     }
  });
ztreer commented 10 years ago

Thank you,

these are useful ideas, i will try to work from here.

Will get back to you with results soon.

ztreer commented 10 years ago

The key seems to be to always look 'a little down', instead of exactly horizontal, so i simply changed the pitch from 0.0 to -6.0 when resetting the camera, and so it will be guaranteed that there will be an intersection point. Using zero pitch did not guarantee that this intersection point will always exist.

I did not experience the issue since then.

Thank you for your help!