How to drag a mesh over another mesh(which is not a Ground)

Hi Forum,

Apologies in advanced if its a super dumb question.

I was trying to implement a feature where I need to drag a mesh(say a window) within the boundary of another mesh(wall).
I saw multiple examples where a mesh is draggable within ground. But is it possible to drag it over another mesh?
Please let me know if there are any example playgrounds.

Thanks

2 Likes

hi @Nitin - Welcome to the forum. They say the only dumb question is the one you don’t ask :smiley:

Have a look at the PointerDragBehavior:
PointerDragBehavior | Babylon.js Documentation (babylonjs.com)

What you are trying to do can be changed by altering the dragPlaneNormal. Hint Vector3(0,1,0) is Vector3.Up(), which is ground dragging, so just change that accordingly.

Next you will want to add also a validateDrag. It may end up looking something like this:

const validateDrag = (targetPosition) => {
  return Math.max(Math.abs(targetPosition.x), Math.abs(targetPosition.z)) <= (GROUND_SIZE / 2) - 10;
}

You can see a working example here, although it is not an imperative example you can always work backwards but for restricting drag the above validation is used and you cannot drag the meshes outside of the ground:
Behaviors - Drag ‘n’ Drop ⋅ Storybook (brianzinn.github.io)

I did something like that recently to do exactly what you are doing, which was drag a window in a wall. That snippet is here:

const dragBehaviour = new PointerDragBehavior({
  dragAxis: new Vector3(1, 0, 0),
});
dragBehaviour.useObjectOrientationForDragging = true;
dragBehaviour.onDragObservable.add((event: {
  delta: Vector3;
  dragPlanePoint: Vector3;
  dragPlaneNormal: Vector3;
  dragDistance: number;
  pointerId: number;
}) => {
  setVersion((v) => v + 1);
  xShift.current += event.delta.x;
});
dragBehaviour.validateDrag = (targetPosition: Vector3) => {
  return Math.abs(targetPosition.x) < 1;
}

dragBehaviour.attach(mesh) 
6 Likes

Impressive explanation :clap: :sunglasses:

Probably you may use SixDofDragBehavior - https://playground.babylonjs.com/#5G9MC5#58
or AttachToBoxBehavior - Babylon.js Playground
See also Docs - Mesh Behaviors | Babylon.js Documentation

1 Like

Thanks a lot for the explanation, I will try it.

Hi Brian,

I am still struggling big time, to keep window confined within the boundary of the wall.
If you dont mind sharing, do you have that snippet where you added window to the wall while ensuring that window mesh is confined within the wall mesh?

Thanks

1 Like

One way to do it is to create an invisible plane right in front of the wall, with size equal to the wall’s size minus the window’s size. Then the validator returns true if the targetPosition intersects the plane.
(old solution) https://playground.babylonjs.com/#YD11CG#3

Edit: here’s an updated version that clamps the position to the boundingPlane to fix the issue that the above solution had of stopping short after a fast drag past the edge. :slightly_smiling_face: :beers:
(new solution) https://playground.babylonjs.com/#YD11CG#6

PS, the reason I used the plane’s bounding box instead of the wall’s bounding box is because the sides of the box would cause the bounding box to be too large, resulting in the window being dragged too far. :slightly_smiling_face:

1 Like

moving-window
There is how it looked. The code to get the bounding box of the window mesh was:

if (windowMesh !== undefined) {
  const { minimumWorld, maximumWorld } = windowMesh.getBoundingInfo().boundingBox;
  console.log('window is:', minimumWorld, maximumWorld)
  modelSize.current = new Vector3(
    Math.round((maximumWorld.x - minimumWorld.x) * 100) / 100,
    Math.round((maximumWorld.y - minimumWorld.y) * 100) / 100,
    maximumWorld.z - minimumWorld.z,
  );
}

In my case I was moving and scaling the window, but you just need to take that into account when validating the new position. I was using CSG to remove the window bounding box from the wall mesh, so that I could make the scene a bit more realistic with shadows. You can see a bit of lag on the wall construction - I only spent 2-3 hours on that, so didn’t work out the details. Your validate drag will just keep the windows so that it doesn’t go outside the wall.

Another thing that might interest you is the gizmo - I am using it in the screencapture to control the light direction, but you can use them also to move meshes around.

3 Likes