Big Gizmo Improvements: Position Screen Space + Rotation Gizmo

Hey ya’ll

Some suggestions to really improve the gizmo UX :slight_smile:

  1. Position screen space dragging. Right now there is only axis + planar
  2. Rotation Gizmo: Dragging anywhere on the gizmo sphere to rotate, instead of just the axes. (Like in Unity)

@Cedric @sebavan

1 Like

This would be a great addition. Feel free to do a PR. I take a note but it might be many weeks before I can start doing something.

Yup agree a PR would be great :slight_smile:

@Cedric I’m pretty new to the gizmo code, so I’m guessing I need to add a new PlaneDragGizmo to positionGizmo.ts and dynamically update the PlaneDragGizmo’s planeDragNormal based on the screen space plane normal

this.screenPlaneGizmo = new PlaneDragGizmo(screenPlaneNormal, Color3.Yellow().scale(0.5), this.gizmoLayer, this);
then dynamically update the screenPlaneNormal within (pointerDragBehavior)?

sounds like a pretty solid plan to try :slight_smile: @Cedric is currently off for a bit so his answers might be delayed.


Yes, I would start doing that way and see how it goes.


I’ve decided to create a PG to test out a simple screen space translation (class ScreenPlaneDragGizmo extends BABYLON.PlaneDragGizmo)

But sometimes the sphere gets bigger and bigger or smaller and smaller, I must be doing something wrong


vector3.forward return (0,0,1), but you need the plane that has its normal equals to the camera forward.
Once fixed, you get this:

Screen Space Gizmo | Babylon.js Playground (

Ok, I tried that in the onDragStartObservable function as well, but it still has the issue (become bigger and bigger/smaller) especially after I had rotated the camera e.g. to the right

It’s as if the z-direction relative to the camera also gets updated.

I also tried setting this.dragBehavior.useObjectOrientationForDragging = false; but didn’t quite work

How else can I update the planeDragNormal relative to the camera direction during drag start?

Let me check.

1 Like

After some thoughts, I would try another way with an intermediate transform, parented to the camera, that will be modified by the gizmo. Then, on drag, apply the same delta translation from that transform to the object:

SS Gizmo translate | Babylon.js Playground (

It looks simpler to me but there is 1 thing remaining to do: the transform absolute position is not updated when the camera moves/rotate. With an observable, simply call gizmoSSTransform.setAbsolutePosition(sphere.position); again.

1 Like

It works with onViewMatrixChangedObservable : SS Gizmo translate | Babylon.js Playground (

1 Like

Thanks Cedric!!
What would be the best way to include this in PositionGizmo.ts (and GizmoManager)? Would love for this feature to be available in BJS by default, since screen space translation is one of the most commonly used features in 3D software after all!

yes, I think this road is easier.

How do we make it robust to say, camera changes? If a scene has multiple cameras and the activeCamera switches etc

Use the camera from the renderlayer if available. Otherwise, the active camera.

What do you think is the best way to add into PositionGizmo.ts? The solution posted relies on an external attachedNode “SSTransform”, which is different from being attached to the actual node (e.g. sphere) that the other position gizmos rely on. So the mechanism is a bit different, wondering how to best consolidate it all into PositionGizmo.ts