xeolabs / xeogl

A WebGL-based 3D engine for technical visualization. Not actively maintained.
http://xeogl.org
Other
1.15k stars 264 forks source link

Allow to dinamically adjust sensitivity of zoom/pan #282

Open tmarti opened 5 years ago

tmarti commented 5 years ago
Description of the problem

I've seen that (f.ex. in the case of zooming), in CameraControl the zoom is applied the following way (for example in touch mode):

if (!panning && checkMode(MODE_ZOOM)) {
    var d1 = math.distVec2([touch0.pageX, touch0.pageY], [touch1.pageX, touch1.pageY]);
    var d2 = math.distVec2(lastTouches[0], lastTouches[1]);
    vZoom = (d2 - d1) * getZoomRate() * touchZoomRate;
}

And this means that the zoom factor is dependant on 3 factors:

First, the touch delta:

var d1 = math.distVec2([touch0.pageX, touch0.pageY], [touch1.pageX, touch1.pageY]);
var d2 = math.distVec2(lastTouches[0], lastTouches[1]);
vZoom = (d2 - d1) * ...

So far so good, as larger is the delta, greater is the zoom.

Second, some fixed constants:

const mouseZoomRate = 0.8;
const keyboardZoomRate = .02;
const touchZoomRate = 0.05;

Those are hard-coded constants.

Finally, a small function which in practice also acts as a fixed constant:

function getZoomRate() {
    var aabb = scene.aabb;
    var xsize = aabb[3] - aabb[0];
    var ysize = aabb[4] - aabb[1];
    var zsize = aabb[5] - aabb[2];
    var max = (xsize > ysize ? xsize : ysize);
    max = (zsize > max ? zsize : max);
    return max / 1000;
}

This means that there is a factor that depends on the scene bounding box on its longest dimension.

The result is that...

For big geometries, when navigating in first person, this means that the camera control is highly sensitive (because the scene bounding box is huge) and navigation inside rooms of a building (for example) is impractial (even a small delta in touches means a huge displacement of the camera forward/backwards).

It would be great to allow to dynamically adjust those constants in order to adjust the sensitivity of the zoom:

const mouseZoomRate = 0.8;
const keyboardZoomRate = .02;
const touchZoomRate = 0.05;

So the question is:

Do you think is it something desriable/doable to support this functionality?

(I can help with the code if you need to)

xeogl version
Browser
OS
Hardware Requirements
tmarti commented 5 years ago

Oh! Just seen #276, which proposes just this change in point 2.

If I can help with anything regarding it, just let me know :-)

xeolabs commented 5 years ago

Hi @tmarti , sorry for the late reply.

Yes, if you like, feel free to make a PR in which the CameraControl exposes those constants as settable properties.

And we would very much like a better automatic technique for adjusting the zoom rate, better than just using the scene AABB, so if you have any ideas for that, we'd love to hear about them!

tmarti commented 5 years ago

Ok, will try to send the PR during this week.

I think it sounds quite difficult to have a general purpose "step size" calculation.

As they suggest in #276, it's not the same to navigate from inside the model than from outside the model.

This is the same problem old 3D games had (and somewhat solved), having the additional restriction that movement should mimic the person's movement (they were mainly first person games), so they could assume to move e.g. at constant walk speed 1m/s, and it was a good decision given that every 1st person game nowadays does +/- the same, maybe as a chase-camera

But when navigating a 3D model of a building, this assumption is not really good.

Actually, I've seen after issue creation thay maybe in my case a better solution is to include some "side move/forward move" UI controls, which will move the camera at constant speed in either dimension.