Jump to content

Camera beta based on mousewheel


Recommended Posts

I am back with another crazy thingy! I have here for your pleasure, a playground! http://www.babylonjs-playground.com/#28AM9V#1

I have some notes at the top of the playground but let me break this shiz down for you.

I am trying to modify the arcRotateCamera's beta based on mouse wheel scroll. I have this sort of working.. well, it does work... BUT, I am having trouble with it; it's choppy and just not right. I'm trying to get it smooth like butter (have easing). The idea is the closer you get to the target, the beta changes so you go from a top(ish) view to more of a 45-40 degree angle looking at the target. Make sense? I just made a hand motion explaining but you can't see it.. trust me.. I did it.

I added some textures to help you see the choppiness. My guess, is I need to maybe use a percentage of a range for the scroll/angle, but I have no clue; math and I do not get along. I could be wrong on that.. not about math and I not agreeing, that I am sure of. I tried calling the angle/scroll event in various places (registerBeforeRender/AfterRender) to try and determine why it's choppy but there was no change.

I was hoping someone smarter than I am could take a look and provide some feedback. 

I suck and need help. thanks.

Link to comment
Share on other sites


So first of all you are registering your event on every frame :)

I'm wondering if you should not handle the mousewheel event and rather use a beforeRender event to check camera radius and deduce beta from there. In this case you will have inertia for free (which will lead to butter smooth animations :))


Link to comment
Share on other sites

looked at my playgound and somehow it seems super screwed up. here it is again not super screwed up http://www.babylonjs-playground.com/#28AM9V#2 just in case.


Thanks @Deltakosh. You mean scene.registerBeforeRender or something else? I thought about using the radius and not the mouse wheel by my brain had exploded at that point. 

Link to comment
Share on other sites

Hi again RC.  http://www.babylonjs-playground.com/#28AM9V#7

Straightened up your playground a bit... but still nothing exciting happening.

Let's look at lines 98 - 109 .  Generally, I emptied your beforeRender slot, because we only need the eventListener adding once per scene, and not every frame, as deltakosh mentioned.  Also notice that I added a scene.onDispose... that removes the event listeners... when the scene unloads.  IF we didn't de-register the listeners, and IF you suddenly chose another playground demo from the list of pre-built ones, then those event listeners would still be active on that new scene you chose.  SO, using scene.onDispose is a wise move for any scene that has added eventListeners.  Just like a picnic in the park, best to cleanup before you leave.  :)

Another thing... notice that I made sure that var setCameraBeta = function (e) happens BEFORE we try to add an event listener that references that function.  First we establish the function (line 66) and then LATER in the code... we "bind" an eventListener to that function (lines 98-99)

Also, the event object is automatically sent as an arg/parameter to the bound event handler function.  That's why (e) is in line 66.  That is the event object... inbound to the handler func.  We need that puppy IN the function... for lines 76 and 78.  I used a console.log (viewable with browser F12 dev tools)... to view the event objects (e) just to make sure they were coming into the handler function ok.

I added line 80, because I was having some problems with scene.activeCamera being null.  Not sure if it is still a problem.  It was... when I was trying some demented things.  :)

In lines 82-93, you are setting beta limits... which is fine, but you could set camera.beta itself.  It all depends upon if you want the user to still be allowed to adjust cam tilt with leftmousebutton-dragging.  Currently, your scene (and method) is disallowing user-done camera tilt.  It's all cool.  If you DID allow a user to do some drag-tilting after a few mousewheel zooms, then if they did more mousewheeling, there would probably be an unwanted "jump", so you might be doing things correct, with that.

This playground is probably working as well as it can, again.  I'll keep thinking.  I think there is an ArcRotateFollowCamera that could be interesting to you.  I think it has positional and rotational offsets.  In other words, it has a value for how close the camera is to the followed target (positional), and also how much the camera is panned or tilted away-from aiming precisely at the target.  Think about that.  IF you could use the mousewheel values to change the follow distance (position), that would be a start. And then, as that distance got smaller, you start making adjustments to the X value of the followCam rotational offset (it's beta).  With a free camera-based followCam... it would use rotation.x.  With the arcRotateFollowCam, it would use the camera.beta value. 

I have never used the ArcRotateFollowCam, but I have used the freeCamera followCamera a few times.

Just some thoughts.  No matter what, you are still going to have problems with un-smooth.... because them darned mousewheel events don't happen very smoothly.

I made another:  http://www.babylonjs-playground.com/#28AM9V#8

In this one, I added a camera.wheelPrecision setting in line 41, and then lowered your angleSpeed 10-fold... in line 70.  I just wanted to see how it felt, and if we could smooth the butter a bit, by doing that.  *shrug*  Maybe this will give us ALL some ideas to work-with.

Btw, I enjoy the comedy in your posts.  I think you and I are going to get-along just fine.  You have a good goofy-quotient.  :)

Link to comment
Share on other sites

@Wingnut if you look at the #1 playground i made i had the onDispose call in there but something got all jacked up and i redid some stuff for playground and it got cleared out.. W@#$R%#$%^@!#$%! is all i can say to that.


I'm trying Dave's suggested approach now but math can eat a big bag of salty d!@&$ for all I care... this is why i studied art.... I'm trying to get a formula worked out for the percentage changes. If my brain explodes and I don't make it back, tell Aunt Milly I'm the one that left the mustard on the counter.

Link to comment
Share on other sites

GUYS GUYS GUYS!!!! I FIGURED IT OUT GUYS!!! OMFG STOP THE PRESS AND GRAB YOUR BUTTER CHURNER BROOMS!!!!! ok, actually, a guy I work with named Dave (ANOTHER FREAKING DAVID!) figured out the formula I am using but whatever, screw him, this is my win. 

http://www.babylonjs-playground.com/#28AM9V#9 is the solution

Sorry @Wingnut but I went with @Deltakosh's idea of not using the mouse wheel at all. This is how it works (pay attention it is about to get all calculated and crap all up in here)

the goal is to sync the two ranges. We do this by using the upper and lower bounds of the camera radius and syncing that percentage change to the upper/lower bounds of the allowed beta range. This gets checked in the registerBeforeRender function. Since I am not longer using the mouse wheel event I don't have to worry about doing extra crap for mobile too, it will just work.


// the numbers here are just to help you process what is going on.
var camera = scene.activeCamera;
var camera_max_radius = 50;
var camera_min_radius = 6;
var cam_radius_range = 44;
var camera_beta_max = 64; // (*degrees)
var camera_beta_min = 45; // (*degrees)
var camera_beta_range = 19; // (*degrees)
var range_difference = camera_beta_range / camera_radius_range; // 19/44

var beta_in_degrees = (camera.radius  - camera_min_radius) * range_difference + camera_beta_min;
var new_beta = deg_to_rad(beta_in_degrees); // **

function deg_to_rad(deg){ return (deg * Math.PI) / 180; }

lets test with some made up numbers to see what the formula actually looks like

current_radius = 44 
beta_in_degrees = ( 44 - 6 ) * 0.43 + 45 = 61.4
beta in radians = 61.4 * 3.14 / 180 = 1.07163216

now, that might make you go.. ummmm ok... but what it means is IT FREAKING WORKS! TEST SUCCESSFUL! 
you may proceed to the next testing chamber.


* arcRotateCamera uses Radians, not degrees, but my brain processes degrees easier

** convert degrees to radians for the arcRotateCamera to understand using the formula:  (deg * Math.PI) / 180


 I have notes in the playground for all of this as well. It is also worthy to note the following: WUBBA LUBBA DUB DUB!

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.

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.


  • Recently Browsing   0 members

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