Snap grid on a plane

I would like to implement a snap grid function in my pointer, but it seems when I zoom in or out, the grid distance changes. Is there a solution for this?

Here is the playground: https://playground.babylonjs.com/#VHW8N9#2

I created the grid using this
scene.pick(Math.round(scene.pointerX/100)*100, Math.round(scene.pointerY/100)*100)

Do you want to restrict pointer movement so it becomes snappy or snap the picked location?

Exactly. I want to restrict the ponter movement to become snappy regardless of the camera position

EDIT: skip this one, solution below

I think we could do it just by hiding the native cursor and use a 3d simulated cursor by doing some magic in the background. Let me think about it for a while :slight_smile:

I did something similar here (the yellow is native cursor, the uggly duck is the simulated one)

Ok, I already have an idea how to achieve this.

The texture you are using currently must be replaced and we have to draw the grid using lines. There is a GridMaterial in BabylonJS though (Grid Material | Babylon.js Documentation), but I am pretty sure we can’t match the exact positions because it would be quite hard to match the exact math used in the GridMaterial shader.

I think we could cast a ray from the camera to the cursor position and calculate the nearest snapping position. I need to finish my regular work so I can come back to this topic in a few hours but this is definitelly an interesting topic for me as well :slight_smile:

However in the example you have provided you’re snapping the plane not the cursor, so are you sure you want to snap the cursor?

EDIT: I have another simpler idea :slight_smile: Have a look at this. It is snapping a box onto the grid. Should be easy to adapt to your needs.

3 Likes

wow that is great. That solve my problem. There is only one thing I would like to clear out. I would like to be able only to snap grid when shift is pressed. My intention is to create walls on a plane like the following playground

This is really easy to achieve, because we have the evt object available so:

            if (evt.shiftKey === true) { // or omit === true if you prefer
                snappedPosition.x = Math.round(pickingInfo.pickedPoint.x)
                snappedPosition.y = Math.round(pickingInfo.pickedPoint.y)
                snappedPosition.z = Math.round(pickingInfo.pickedPoint.z)
            } else {
                snappedPosition.copyFrom(pickingInfo.pickedPoint)
            }

EDIT:
You can set this to 1. Previous value was 100.
image

Thank you for helping me out

1 Like

You are welcome!

1 Like