Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve scaling specs when executing webgl's orbitControl() #6104

Closed
1 of 17 tasks
inaridarkfox4231 opened this issue Apr 14, 2023 · 3 comments · Fixed by #6105
Closed
1 of 17 tasks

Improve scaling specs when executing webgl's orbitControl() #6104

inaridarkfox4231 opened this issue Apr 14, 2023 · 3 comments · Fixed by #6105

Comments

@inaridarkfox4231
Copy link
Contributor

Increasing Access

Currently, webgl's orbitControl() has a stuttering issue when scaling with mouse scroll.

The reason for this is that the _mouseWheelDeltaY is not directly used for judgment in the orbitControl() function, and for some reason the difference from the previous one is taken. This is unnecessary processing.

if (this._mouseWheelDeltaY !== this._pmouseWheelDeltaY) {
  // zoom according to direction of mouseWheelDeltaY rather than value
  if (this._mouseWheelDeltaY > 0) {
    this._renderer._curCamera._orbit(0, 0, sensitivityZ * scaleFactor);
  } else {
    this._renderer._curCamera._orbit(0, 0, - sensitivityZ * scaleFactor);
  }
}

Another problem is that the distance to the gaze point is changed by addition and subtraction when scaling in _orbit().

camRadius += dRadius;

// prevent zooming through the center:
if (camRadius < 0) {
  camRadius = 0.1;
}

With this, if the scale is small, it will move too much, and if the scale is large, the distance will not change easily, making it difficult to operate comfortably.
Usability can be compromised, for example, when executing code such as:

function setup() {
  createCanvas(800, 640, WEBGL);

  // case:1 (small scale)
  camera(0, 0, 1, 0, 0, 0, 0, 1, 0);
  perspective(PI/3, width/height, 0.1, 10);

  // case:2 (large scale)
  //camera(0, 0, 1000, 0, 0, 0, 0, 1, 0);
  //perspective(PI/3, width/height, 100, 10000);
}

function draw() {
  background(220);
  orbitControl();

  // case:1
  box(0.2);

  // case:2
  //sphere(200);
}

Also, there is no necessity for the number 0.1. Smaller scales are possible, and larger scales are practically meaningless.

I would like to make suggestions to improve these problems.

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build Process
  • Unit Testing
  • Internalization
  • Friendly Errors
  • Other (specify if possible)

Feature enhancement details

First, it is unnatural that only sensitivityZ is set to 0.5, so set it to 1.

before:

  sensitivityZ = 0.5;

after:

  sensitivityZ = 1;

Next, we will only use _mouseWheelDeltaY to determine if it is 0, and we will specify a scaling factor of 0.02 (not sure if this is a good value).

before:

if (this._mouseWheelDeltaY !== this._pmouseWheelDeltaY) {
  // zoom according to direction of mouseWheelDeltaY rather than value
  if (this._mouseWheelDeltaY > 0) {
    this._renderer._curCamera._orbit(0, 0, sensitivityZ * scaleFactor);
  } else {
    this._renderer._curCamera._orbit(0, 0, - sensitivityZ * scaleFactor);
  }
}

after:

const zoomScaleFactor = 0.02;
if (this._mouseWheelDeltaY !== 0) {
  // zoom according to direction of mouseWheelDeltaY rather than value
  if (this._mouseWheelDeltaY > 0) {
    this._renderer._curCamera._orbit(0, 0, sensitivityZ * zoomScaleFactor);
  } else {
    this._renderer._curCamera._orbit(0, 0, - sensitivityZ * zoomScaleFactor);
  }
}
this._mouseWheelDeltaY = 0;

Filally, In _orbit(), when changing the distance from the gaze point, take the base 10 logarithm and change it there. Also, for the distance, refer to cameraNear and cameraFar and limit the movement accordingly.

before:

camRadius += dRadius;

// prevent zooming through the center:
if (camRadius < 0) {
  camRadius = 0.1;
} 

after:

camRadius = Math.log10(camRadius);
camRadius += dRadius;
camRadius = Math.pow(10, camRadius);

// prevent zooming through the center:
if (camRadius < this.cameraNear) {
  camRadius = this.cameraNear;
}
if (camRadius > this.cameraFar) {
  camRadius = this.cameraFar;
}

I have provided sample code with these changes applied. You can check it here.
improve zooming

@inaridarkfox4231
Copy link
Contributor Author

I wrote it in 3 lines for the sake of clarity, but it may be more concise to multiply the powers of 10 as follows.

//camRadius = Math.log10(camRadius);
//camRadius += dRadius;
//camRadius = Math.pow(10, camRadius);
camRadius *= Math.pow(10, dRadius);

// prevent zooming through the center:
if (camRadius < this.cameraNear) {
  camRadius = this.cameraNear;
}
if (camRadius > this.cameraFar) {
  camRadius = this.cameraFar;
}

I would like to create a pull request based on these suggestions.

@davepagurek
Copy link
Contributor

While we're at it, do you think we should make sensitivityZ * scaleFactor should also multiply by this._mouseWheelDeltaY so that devices like trackpads that can scroll at different speeds aren't limited to a constant scroll rate?

@inaridarkfox4231
Copy link
Contributor Author

I looked at easyCam, but 0.01 times deltaY was fixed and the acceleration multiplied there was changed by the method.
I think it's difficult to deal with differences between devices, so I think the only way to deal with it is to set SensitivityZ appropriately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants