How to make measurement plugins ignore two-finger touch used for pan or zoom?
We need to be able to robustly handle two-finger touch for panning and zooming, while the measurement controls are active.
When making a measurement with DistanceMeasurementsPlugin or AngleMeasurementsPlugin, these plugins work fine when we're using single taps, for camera rotation,, which enables us to rotate the camera while the plugins are active, and while in the middle of creating a measurement.
When about to make a measurement, or in the middle of making a measurement, and we use two fingers to pan or zoom the camera, the measurement plugins get confused, however, and will start a new measurement or complete the measurement we're currently making.
How to make these plugins ignore a two-touch drag to pan or zoom, while the measurement controls are active?
One possibility might be to use the TouchEvent identifier property to track specifically the single-touch event we're building each measurement with, to ignore any others (like the two-finger for zoom/pan that's handled by CameraControl) but that property is not supported by Safari.
Demos
- https://xeokit.github.io/xeokit-sdk/examples/measurement/#angle_createWithMouse_snapping
- https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_createWithMouse_snapping
Hey @tmarti , @Amoki , @Kurtil - could I please get your opinions on this - a possible solution for this issue - make a long-touch the only way to set endpoints for measurements.
For feedback to the user, we might have a shrinking circle at the pointer, which shrinks as the log-touch timeout runs.
While shrinking, the touch indicates camera control. As soon as its fully shrunk, the pointer represents setting of a measurement end point, eg.
Screencast from 09.10.2023 13:49:31.webm
Maybe also reduce the timeout for long-touch down to 300ms (currently it's 500ms). This way, there would be no interference with CameraControl touch input.
Currently we already use long-touch to activate snapping for measurements. We could make it so that snapping is explicitly to be activated for touch in the same way as we do for mouse. For mouse, snapping always happens on each click if it's enabled on the measurements controls.
UX idea as mentioned above, for when snapping is explicitly enabled for measurements.
- Long touch always required to set measurement end points
- As soon as touching, show a circle at the position we'll snap to
- On long touch timeout, set the position at the snapped location, open lens view and allow user to drag to dynamically re-snap to a new position
- If touch ends before circle collapsed, cancel setting the point
If snapping is not enabled, then none of the above happens, and the position is just set immediately on touch-release.
This looks promising, and is easy to use - double-tap to set each position endpoint.
- Double-tap to set point, snapped to nearest vertex or edge.
- On each double-tap, immediately release on second tap to set the point, or hold down on second tap to continue snapping the point.
- When measurements controls are not active, double-tap can still be used to view-fit objects as usual.
- User doesn't need to wait for long touch timeout, so setting points is quicker.
Screencast below is not showing the touch pointer, however, so doesn't really show much, other than that it's quick..
Sorry for the delay in joining the party, but there we go!
@xeolabs so your problem is what happens when you are dragging the finger (after long-tapping and before releasing it) and then you enter the two-touch mode, right? You are alluding to the fact that then the Pan/Zoom handlers kick-in.
In the PoC code I sent you (even though it was poorly documented 🙏), the solution I found was to inhibit camera-related input-controllers.
The rationale was that, when the measurement-controller enters long-press mode, it should get exclusive access to the managing touches input, just becaude of the effect you're suffering.
In xeokit-sdk, there are multiple handlers for same input events (be it mouse or touch events).
So, the events related to the-press state were (in that state machine diagram):
- single-tap long-press detected: enter long-press state
- (while in long-press state): inhibit every other handler from receiving input events => this is what solves the problem with which you started this thread
- after releasing last touching finger: un-inhibit the rest of input handlers
Kind-of, the idea is that: in long-press mode, who can proceds input events is only the input handler of the measurement controller, just to make sure it does not get suddently "disturbed" by other plugins tampering with the scene (camera controllers, section plane gizmo handlers, ...)
No problem @tmarti !
Gotcha - IMO it would be great though if the user could rotate and pan the model while making a measurement, so as to be able to locate each endpoint independently (think of that Lyon City model, being able to hunt down two distantly-spaced landmarks).
However, following this PR, we can now bundle many different controller components for users to choose from, so we could easily a controller that does block touch input from CameraControl in this manner, if that is to the user's taste, along with another one that always requires double-click to set each endpoint, and another that always requires long-touch, etc.
So, I'll take a shot at fixing up the controller that does both short-touch and long-touch with CameraControl blocking, and bundle that as well.
we can now bundle many different controller components for users to choose from, so we could easily a controller that does block touch input from CameraControl in this manner, if that is to the user's taste, along with another one that always requires double-click to set each endpoint, and another that always requires long-touch, etc.
Interesting idea 👌
So, I'll take a shot at fixing up the controller that does both short-touch and long-touch with CameraControl blocking, and bundle that as well.
👌👌👌