Jump to content

ArcRotateCamera goes crazy when moved past zero on beta axis


Sigmus
 Share

Recommended Posts

Hello everyone,

I'm currently building an object viewer with BJS that utilizes a single ArcRotateCamera. I had to create manual control buttons for the camera, because apparently it can't be expected of the average web user to know how the simple concept of drag and drop works. So, I built 6 button to rotate the camera up, down, left and right and zoom in and out. The beta axis needed some special attention, because the application's state machine can have a state where upperBetaLimit and lowerBetaLimit are null, so the user can rotate past the top / bottom. This works fine with the mouse, but when the button is used and the last rotation modification moves the beta value past zero/360 degrees, the camera's z-axis (which should be fixed and not even modifiable for ArcRotateCamera) flips upside down for a split second before some sort of internal correction seems to turn it back around to normal. But that moment is very irritating and I doubt that my client will approve the app with such an ugly display bug. Any idea what might be causing it and how to get rid of it? I already tried to prevent the beta value from ever reaching exactly zero, because I expected that this was the problem, but as it turned out, that was not it.

Here is the code for the up button:

$('#buttonRotateUp').on('mousedown touchstart', function (e) {
  e.preventDefault();
        
  if (window.camBetaRotationInterval) {
    clearInterval(window.camBetaRotationInterval);
  }
  $('#buttonRotateDown').removeClass('limit-reached');
          
  if (!$(this).hasClass('pressed') && !$(this).hasClass('limit-reached')) {
    $(this).addClass('pressed');
    var rotateStep = 0.15;

    // checking if the limits are not null
    if ((scene.activeCamera.lowerBetaLimit || scene.activeCamera.lowerBetaLimit === 0) && scene.activeCamera.upperBetaLimit && (scene.activeCamera.beta + rotateStep) > scene.activeCamera.upperBetaLimit) {
      $('#buttonRotateUp').addClass('limit-reached');
      scene.activeCamera.beta = scene.activeCamera.upperBetaLimit;
    } else {
      if ((scene.activeCamera.beta + rotateStep) == 0.0) {
        scene.activeCamera.beta += (rotateStep + 0.1);
      } else {
        scene.activeCamera.beta += rotateStep;
      }
    }
    window.camBetaRotationInterval = setInterval(function () {
      var $btn = $('#buttonRotateUp');
      var rotateStep = 0.015;
      if ($btn.hasClass('limit-reached') || ((scene.activeCamera.lowerBetaLimit || scene.activeCamera.lowerBetaLimit === 0) && scene.activeCamera.upperBetaLimit && (scene.activeCamera.beta + rotateStep) > scene.activeCamera.upperBetaLimit)) {
        $btn.addClass('limit-reached');
        scene.activeCamera.beta = scene.activeCamera.upperBetaLimit;
      } else {
        if ((scene.activeCamera.beta + rotateStep) == 0.0) {
          scene.activeCamera.beta += (rotateStep + 0.01);
        } else {
          scene.activeCamera.beta += rotateStep;
        }
      }
    }, 25);
  }
}).on('mouseup touchend', function (e) {
  e.preventDefault();
       
  $(this).removeClass('pressed');
  if (window.camBetaRotationInterval) {
    clearInterval(window.camBetaRotationInterval);
  }
});

 

Link to comment
Share on other sites

Thanks for the reply. Upper and lower limit can be null because I explicitly set them to be null when a certain condition is met. Doing so results in the camera behavior I intended to achieve: Being able to rotate past the default stopping positions of the top-down and bottom-up view. And it works fine as long as I use the mouse for that. When I click the vertical rotation buttons, then the ugly flickering I described occurs.

I was able reproduce it in the playground:
http://www.babylonjs-playground.com/#1AYE5Y#2

As you can see there, the knot rotates around the beta axis. Every time it goes past the 0/360 degree point (which would normally be the top-down-view stopping point if I hadn't removed the limits) the camera has this ugly flicker effect where its view seems to be turned on the head for a split sec. I have no idea how to get rid of that and I definitely need a smooth rotation animation for my current project.

Link to comment
Share on other sites

Thanks a lot for the quick reply and the work you put in this. I saw that the only change in the demo code (except for smooting out the animation as a bonus) was to disable collision. So if I understand you correctly, this means that the bug in the upsideDown model you mentioned was a fix for the actual Babylon engine you just implemented? Very cool. So, which version do I need to make it work? The latest nightly alpha of 3.0? This might be a bit risky, considering that I'm using a stable 2.5 release for my project. Or did you fix it for BJS 2 as well?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...