3DTilesRendererJS icon indicating copy to clipboard operation
3DTilesRendererJS copied to clipboard

Add middle-click + drag listener for ZOOM on EnvironmentControls

Open jo-chemla opened this issue 1 year ago • 5 comments

Is your feature request related to a problem? Please describe.

The EnvironmentControls parses left and right clicks + mouse-wheel events, (Quick note, the SHIFT + LEFT_CLICK did not trigger rotate during my tests). It could be nice if these controls could also parse Middle click for zoom - the awy it is done in googleMapsAerial within OrbitControls

Describe the solution you'd like

Web/API/Pointer_events suggest adding to PointerTracker.js

isMiddleClicked() {
  return Boolean( this.buttons & 4 );
}

And then this could probably resort to something like the following addition to EnvironmentControls.js - pointerdownCallback

else if ( pointerTracker.isMiddleClicked() ) {

	// if the clicked point is coming from below the plane then don't perform the drag
	this.setState( ZOOM );
	this.zoomDirectionSet = false;
	this._updateZoomDirection();

        // The below could be shared on top if the `if (hit)` block
        this.pivotPoint.copy( hit.point );
        this.pivotMesh.position.copy( hit.point );
        this.pivotMesh.updateMatrixWorld();
        this.scene.add( this.pivotMesh );
}

Finally,

  • or replicate somehow the wheelCallback and replace how it handles event cursor e.deltaY motion with movementY, and apply to zoomDelta, but build this into pointermoveCallback:
	const pointermoveCallback = e => {
	// ...
	// Add mouse click handle in pointerMove
	if ( this.state === ZOOM ) {

		console.log( 'MOUSE MIDDLE CLICKED: ', e, e.deltaMode, e.deltaY );
		const delta = e.movementY;
		// use LOG to scale the scroll delta and hopefully normalize them across platforms
		const deltaSign = Math.sign( delta );
		const normalizedDelta = Math.log( Math.abs( delta ) + 1 );
		this.zoomDelta -= 3 * deltaSign * normalizedDelta * 1;
		// this.needsUpdate = true;

	}

Describe alternatives you've considered

Use another controls, like Pivot controls instead of EnvironmentControls to handle middle-mouse click

jo-chemla avatar Oct 07 '24 10:10 jo-chemla

I'm open to adding the feature if you like to make a PR!

gkjohnson avatar Oct 07 '24 11:10 gkjohnson

Just did a try, seems like this is working! https://github.com/NASA-AMMOS/3DTilesRendererJS/pull/789

jo-chemla avatar Oct 07 '24 11:10 jo-chemla

Edit: seems that terrain avoidance makes it not exactly work like mouse-wheel - where the cursor stays at the same spot on the mesh during zooming-in/out, while it slides with the middle-click zoom. Maybe an update that should be disabled or enabled that I am missing - something like zoomDirection or pivot?

jo-chemla avatar Oct 07 '24 11:10 jo-chemla

seems that terrain avoidance makes it not exactly work like mouse-wheel - where the cursor stays at the same spot on the mesh during zooming-in/out, while it slides with the middle-click zoom. Maybe an update that should be disabled or enabled that I am missing - something like zoomDirection or pivot?

I'll have to try it when I'm on a computer with a mouse but I wouldn't expect this to keep the terrain in the same spot under the mouse since the cursor is being dragged. It should zoom into the point that was originally clicked.

gkjohnson avatar Oct 07 '24 12:10 gkjohnson

Yes I agree it should zoom on the spot originally clicked, but this spot seem to slide a little because of the terrain constraint. It's not very noticeable, but still a bit weird.

It might be trying to zoom always to where the cursor is, which when middleclicking + sliding vertically, moves towards the top or bottom of the screen. Conditioning _updatePosition and _updateRotation on controls update only to when state is ROTATE or DRAG also seem to be reducing the issue:

if ( state === ZOOM && zoomDelta !== 0 ) {
  this._updateZoom();
  this.rotationInertia.set( 0, 0 );
  this.dragInertia.set( 0, 0, 0 );
}
else if ( state === ROTATE || state === DRAG ) {
  this._updatePosition( deltaTime );
  this._updateRotation( deltaTime );
}

jo-chemla avatar Oct 07 '24 15:10 jo-chemla