Jump to content

How To Create Camera Custom Inputs?


Rolento
 Share

Recommended Posts

Hi All

I have a 3D scene (a house) and I am wanting to navigate the scene using mouse inputs that similar to that used in other 3D CAD software applications. 

Specifically I am trying to acheive the following:-

MIDDLE MOUSE BUTTON:    PAN LEFT / RIGHT / UP / DOWN
MIDDLE + RIGHT MOUSE BUTTON:    ROTATE X/Y/Z
MOUSE WHEEL:    ZOOM IN / OUT

Using the above controls you will see it is not possible to move/pan the camera position IN/OUT however it is possible to rotate, pan and zoom on the object of interest.    Effectively the PAN mouse inputs will enable the focal point of the camera to be repositioned in 3D space, all ROTATE and ZOOM actions are performed around this 3D point.

Hopefully the explanation of what I am trying to do is understable. 

I have tried using ArcRotateCamera (e.g.)

    var camera = new BABYLON.ArcRotateCamera("camera1", -90*Math.PI/180, -180*Math.PI/180, 100, new BABYLON.Vector3(0, 0, -0), scene);
    camera.lowerBetaLimit = -Math.PI;
    camera.upperBetaLimit = Math.PI;
    camera.allowUpsideDown = true;
    camera.checkCollisions = false;
    camera.panningSensibility = 20;

This camera is a good starting point but it does not achieve my goal (as above) - i.e. panning and rotations do not work as I desire. 

I wanted to know if it was possible to override the inputs for a given instance of a camera (i.e. so I can remap the mouse inputs and override how rotations and panning is handled).  However, I have not found a post that explains this ability. 

I am slowly coming to the conclusion that you have to create your own custom camera.  I have read [ https://doc.babylonjs.com/tutorials/Customizing_Camera_Inputs#configure-your-inputs ] but it is not clear to me what I am supposed to do...  I did a Frankenstien experiment (I literally created a monster) by creating a new custom input based off the "class FreeCameraMouseInput implements ICameraInput<FreeCamera>".  To do this I did the following: (a) extracted the TypeScript code, (b) converted it to JavaScript, (c) referenced it as a new input for my camera - NOTE: I did not make any changes to the TypeScript file.  Here is the result (see lines 9~10):

http://www.babylonjs-playground.com/#1RGN1Y#2

The inputs seem to be working - but I am not sure what I am supposed to do next to configure the input configuration as defined at the beginning of this post. :(  If you look at lines [ 101~103 ] you will see I added some logic to capture the mouse wheel event - but I do not know how to obtain the wheel delta (e.wheelDelta).  I also do not know how to detect the middle + right mouse button press event...  

If anyone can guide me (or possibly tweak the playground code) I would very much appreciate.

Thanks

Rolento

Link to comment
Share on other sites

Hello

You went to the right conclusion :) Creating your own input is the key here.

You can use this input as a starting point:

https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.ts (https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.js)

You can then apply the change you want for panning or rotation and register this input instead of the main one (Which is basically what you did :))

Here is the input used to control wheel (and more precisely the line used to register to wheel changes): https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.mousewheel.ts#L33

For middle+right mouse, you simply have to test evt.buttons: https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.ts#L50

 

Link to comment
Share on other sites

Hi Deltakosh

Thanks for you guidance.  I spent a little time researching the files you specified and did a little experimenting today.  However... it seems I am stuck.  Please see below:

Step 1) Cloning

https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.ts (https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.js)

I successfully cloned the above functionality and created my own custom input handler.

Step 2) Create custom mouse button event handler:

https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.ts#L50

I did two things (a) register middle mouse button as the panning button, (b) tweak the panning event handler function to react only to the middle mouse button.  With that plan in mind I did the following:

a ) register the middle mouse button:

b ) update the event handler function:

After making the above changes he panning functionality is now invoked when the middle mouse button is pressed (great!).

Step 3) Create middle + right mouse button for rotation

Here I am a little stuck - basically I moved the rotation logic (from the single left mouse click) to the new two button mouse click region I created.  I then check evt.buttons for value "6" which equates to middle and right mouse button:

The expected result is that now when the user presses "left mouse button" nothing happens and when the user presses "middle + right mouse buttons" the rotation functionality is invoked.  The good news is that the rotation functionality is invoked, however the 3D model is rotated rapidy and its pretty much impossible to control.  I dont understand why this occurs given the fact that the same rotation functioanlity (as per the left mouse button) is being invoked.  Do you have any ideas?

More bad news I am afraid - I created a smple scene using the PlayGround but for some strange reason the middle + right click event handler is not invoked (see lines: 133 ~ 139):

http://www.babylonjs-playground.com/#1RGN1Y#3

NOTE: lines 133~139 are invoked on my local installation...

Once again, if you could provide a little more guidance I would appreciate it. 

Thanks

Rolento

Link to comment
Share on other sites

Hi Deltakosh

I forgot to add the mouse wheel event handler - I added it and that works fine:

http://www.babylonjs-playground.com/#1RGN1Y#4

So the only problem to resolve is the middle + right mouse click handler - i.e.

a ) why does it not work in the playrgound code (as per above) ?

b ) why does the rotation go crazy when using middle + right mouse button ?

Thanks

Rolento

Link to comment
Share on other sites

Hi Deltakosh

Im not sure how to simplify the PG but I can explain what I did:

1) Instantiated custom camera: lines 6 ~ 16

2) Added mouse wheel functionality to custom camera: lines 65 ~ 86

3) Added middle + right mouse button logic: lines 152 ~ 158

These are the only changes I made to the original ArcRotateCamera code that I copied.  The issues that remain iare why the middle + right mouse button logic (a) does not work in PG but does locally, (b) when running locally the camera orientation goes haywire. 

Thanks

Rolento

Link to comment
Share on other sites

Hi Deltakosh

> Mouse wheel is working (at least for me)

Correct.

> Based on a rapid analysis, pointA && pointB is always false (line 151)

Ok, but do we have any idea why that might be when using the PG - i.e. when I run the same code from my local machine the middle+right mouse buttons are working (but the rotation is all messed up). 

Please be aware that I have not altered line 151 (it is taken directly from the file/source that you recommended above).  So perhaps there is an error the original source file - i.e. perhaps multi-button functionality is not working?  If I get a chance I will investigate further.

Link to comment
Share on other sites

FYI

I inserted the following code (line 152):

alert( "PointA: " + JSON.stringify(pointA, null, 4) + "\nPointB: " + JSON.stringify(pointB, null, 4))

If I run the code from the source code located on my HDD I get the following when two mouse buttons are pressed (see attachment)

If I run the code from PG line 152 is not invoked - so it appears the logic for detecting two mouse buttons is being suppressed.  Interstingy if you add a similar alert statement at line 137 you will see that the single mouse click handler is working fine (for all buttons).

dialog.png

Link to comment
Share on other sites

Hi Deltakosh

To fix the PG code your idea is good, so I gave it a try (I altered line: 151)

http://www.babylonjs-playground.com/#1RGN1Y#5

Unfortunately the code still does not work - it can be seen that the PG environment is for some reason only receiving the left mouse click event (i.e. all other mouse click events are discarded/blocked).  So the issue here is the PG environment - not the code it seems.

As the PG is not working correctly I have attached a simple RAR file which contains the same code but configured for running locally.  Could you possibly install the code locally and take a quick peak at the original rotation problem that I reported? 

If you do get a chance please try the following simple test:

a ) press middle+right mouse button and move mouse cursor slowly up

b ) press middle+right mouse button and move mouse cursor slowly down

c ) repeat steps a + b a few times

You will see that after a short period the rotation gets very confused - it seems to be linked to inertia and a stange lag in movement.  I looked at the code and I could not see anything obvious that would be causing this - so I am lost on this one... :(

Any help you (or anyone) can provide would be much appreciated.

Thanks.

Custom Camera.rar

Link to comment
Share on other sites

Hi Deltakosh

I really appreciate your efforts, the fix you provided gets me a step closer - but on closer inspection I can see lots of javascript errors are being thrown - so something is not quite right. 

I did some more experimenting with my local code base (to get around the mouse button issue encountered in the PG).  It is really odd, when I link the camera rotation code/logic to the LEFT, MIDDLE or RIGHT single mouse button everything works fine, but when I link the same code/logic to the MIDDLE+RIGHT mouse buttons the rotation gets all messed up and confused. 

I assumed that perhaps multiple mouse button event handlers were being invoked - so I added debug comments for each of the event handlers, but no problem was detected (i.e. only the MIDDLE+RIGHT mouse button event handler was being invoked).

So in conclusion I have to admit defeat on this one.  I will revert back to using the default LEFT mouse button for rotations (because that works just fine).  At a later date when I have more time I will look into this issue again and try and find out what is going wrong.

Once again, thanks for your help - I learnt a lot.

 

Link to comment
Share on other sites

  • 1 year later...

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...