Move Environment with Key ALT and mouse

Hi,

how i can make move Environment with skybox with Keyboard ALT key and hold right click on mouse and move on Y axis.

Does anyone perhaps have an example?

1 Like

Do you just want to strafe/pan the camera ?

@PolygonalSun might be able to help

1 Like

Hello there!

Had some time so I thought I’d take a crack at it. Here is a little demo I made to showcase what I think you are looking for. When the alt and mouse are pressed the world will pan in the direction of the mouse. https://playground.babylonjs.com/#SRZRWV#638

Let’s take a little in depth look on how to achieve this. First I used an arc rotate camera. I think the arc rotate camera is best for this scenario because your scene will be the center of attention. However for the panning we are going to take that center and then offset it based on the mouse click. To do this we will need onPointerObservable (line 96) for when the mouse is down.

Now for the tricky step, applying the math. :joy: If you take a look at the inertialPanningFn (line 76) you will see how we take the scene.pointer.X and scene.pointer.Y to get a position. Then we can use it to get the difference

const directionToZoomLocation = initialPos.subtract(pos);
const panningX = directionToZoomLocation.x * (1 - camera.inertia);
const panningY = directionToZoomLocation.y * (1 - camera.inertia);

Finally we set the target on the camera which is now our “offseted” center.

camera.target.addInPlace(inertialPanning);
inertialPanning.scaleInPlace(camera.inertia);

And there you have it. Let me know if you have any questions :slight_smile:

Bonus: Here is another example which includes zooming as well if you are curious! https://playground.babylonjs.com/#5QBZT0#9

6 Likes

I just wanted to provide an additional way to handle the input part of this. Specifically, for the ArcRotateCamera, you can actually place a value in the inertialPanningX/Y variables and it will move the camera as needed.

// You can use onPointerObservable to add a move that pans when the Right-Click and Alt key are pressed
scene.onPointerObservable.add((eventData) => {
    // Check 'buttons' to see if Right-click (2) is active and altKey is true
    if (eventData.event.buttons === 2 && eventData.event.altKey) {
        // Pan on y-axis based on PointerEvent's movementY (delta) value.  
        // Note: that this will not work on all browsers and you may need to look at other variables for delta
        camera.inertialPanningY = eventData.event.movementY / camera.panningSensibility;
    }
// Only run this during a POINTERMOVE event
}, BABYLON.PointerEventTypes.POINTERMOVE);
4 Likes

I want rotate a Mesh on rotation.y

    newScene.onPointerObservable.add((eventData) => {
      // Check 'buttons' to see if Right-click (2) is active and altKey is true
      if (eventData.event.buttons === 2 && eventData.event.altKey) {
        const w = engine.getRenderWidth(),
              h = engine.getRenderHeight();
            const deltaX = (2 * (newScene.pointerX - w / 2)) / w,
              deltaY = (2 * (newScene.pointerY - h / 2)) / h;

            const beautySkyBox = newScene.getMeshByName("beautySkyBox");
            beautySkyBox.rotation.y = deltaX;
      }
    }, BABYLON.PointerEventTypes.POINTERMOVE);

I can move it, but only -80 and to 80 … I want move it around. from 0 to 360. How i can calculate this?

And how i can prevent move camera if altKey button is active?

So it looks like the math that you’re using to calculate deltaX will only ever have a value of -1 to 1 (while within the bounds of the canvas). Because rotation is calculated in radians, I’d recommend the following:

const deltaX = (2 * Math.PI * (newScene.pointerX - w / 2)) / w

With PI in the equation, your value should be from -PI to PI, which should cover a full rotation. If you want something closer to 0 to 2 * PI (0 to 360 degrees), you could try the following:

const deltaX = 2 * Math.PI * (newScene.pointerX / w)

Since pointerX will be a value of 0 to canvas width (with the bounds of the canvas), this should give you the radian values needed to cover a full rotation.

Finally, if you want to disable the camera while the Alt Key is pressed, you could try using camera.detachControl when Alt is active and just call camera.AttachControl when you get a keyup event with respect to the Alt key.

4 Likes

Ok this works now good:

    var lastPointerX = 0;
    var altPressed = false;
    newScene.onPointerObservable.add((eventData) => {
      // Check 'buttons' to see if Right-click (2) is active and altKey is true
      if (eventData.event.buttons === 2 && eventData.event.altKey) {
        const beautySkyBox = newScene.getMeshByName("beautySkyBox");

        var diffX = newScene.pointerX - lastPointerX;
        beautySkyBox.rotation.y -= diffX * 0.002;
        lastPointerX = newScene.pointerX;
      }
    }, BABYLON.PointerEventTypes.POINTERMOVE);

    newScene.onPointerObservable.add(() => {
      lastPointerX = newScene.pointerX;
    }, BABYLON.PointerEventTypes.POINTERDOWN);

    newScene.onKeyboardObservable.add((kbInfo) => {
      switch (kbInfo.type) {
        case BABYLON.KeyboardEventTypes.KEYDOWN:
          if (kbInfo.event.key == "Alt") {
            if (!altPressed) {
              altPressed = true;
              newScene.activeCamera.detachControl();
            }
          }

          break;
        case BABYLON.KeyboardEventTypes.KEYUP:
          if (kbInfo.event.key == "Alt") {
            if (altPressed) {
              altPressed = false;
              newScene.activeCamera.attachControl();
            }
          }
          break;
      }
    });

With this i can rotate big mesh. But now i have 3 PointLights and want rotate this around a Mesh:

How i can do that?

cc @PolygonalSun

I have make a playground. I think i have a solution. Any improvements?

With ALT + right click hold, you can move around. Important is that Background is sync with pointlight.

https://playground.babylonjs.com/#E7R8F8#7

2 Likes

This is fantastic and reminds me of some character creators in video games that have the same functionality! Very useful demo and clever that you rotate the background instead of the camera with the model. Well done!

(Nit pick question, why is it alt and right click instead of left? Since I already use left for the mouse rotation before)